Skip to content

chore(upstream): merge WebKit AOT compiler rewrite - #53

Draft
vincentkoc wants to merge 21 commits into
openclaw/mainfrom
claude/sync-webkit-aot-rewrite-20261109
Draft

vincentkoc wants to merge 21 commits into
openclaw/mainfrom
claude/sync-webkit-aot-rewrite-20261109

Conversation

@vincentkoc

@vincentkoc vincentkoc commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Problem and change

Sync the OpenClaw engine fork through upstream AOT rewrite 5a61071f79134bf41844e7ea31a8449147d85dd4, retaining the fork fixes and complete commit history. Bun's rewritten compiler at upstream 2596ac5d requires this schema; historical S archives cannot qualify it.

Merge commit required. Do not squash or rebase. Signed merge 2f8b517de6b6b1fc3261bceb39588bf0e13c140e retains parents 8c0ebbe34c570ae20ee14f433a62e83bb6ccf0c6 and 5a61071f79134bf41844e7ea31a8449147d85dd4. Current signed head: 651eeaca6e27.

Port distinct require/import namespaces to the new runtime, retaining marker isolation, shared live exports, GC roots and mock/cache invalidation. Move dynamic CommonJS parent reachability to the scanner, thin-summary and loader-replacement owners. Hook registration alone must not escape the parent; legacy resolver/require replacements must retain it. Preserve upstream's removal of old ValueFlow/CallModules passes and blanket private-evaluator roots.

Signed 1ed3a4477af3 also ports the rewritten typed-array allocation fast path to the fork's existing heap contract: typed-array subspace, complete packed weak-link/mode initialization, list registration and exact logical payload accounting after both allocations succeed. Existing Instance VM plus Heap offsets preserve the Instance ABI. The native fixture checks prior head/counter state, packed links, unrounded payload bytes and unchanged slow exits. Signed a5f127f226d5 requires that exact native case.

Candidate and validation

Qualification now pins signed Bun 0dd6a8f4fc, tree 90e7bca7e472288efe7f5d58b2913d55863bca96. This records an unqualified candidate. Baseline/lane identities, the 85-file selection, size limits, archive/provenance gates and adapter patch inputs/digests remain unchanged. All four migrated IR regressions, three non-trim AOT mock suites, five native namespace cases, 17 module-program cases and the exact typed-array stub case remain required; missing/skipped sources fail qualification.

Bun run 42579667012 on candidate 0dd6a8f4fc passes the full Bun/engine build, runtime engine identity, packaging and Rust trimming-policy tests. Its IR gate still passes three of four: closed-image/bounded-host setup alone cannot isolate a direct function export, which upstream deliberately exposes to the host. The independently reviewed next Bun repair aa024e5a1d wraps the hidden closure in a plain exports object and updates both callbacks to read parent.exports.hidden; existing assertions remain intact. Its native trial against engine 651eeaca6e27 passes the full build, exact engine-identity startup, packaging and Rust trimming-policy tests and all four engine IR regressions. The broader runtime suite reaches its existing 20-minute deadline with failures; qualification fails. Source-proven Bun startup, SQLite, data-URL and fs-test repairs plus HTTP cleanup diagnosis are in progress. The verified Bun report artifact 13659027540 is 4,381,277 bytes, SHA-256 cf1487a1b4009f6e9c805bec4e151fc440d345d279d573e630b5dbd1a22f7d0f. This engine branch still records candidate 0dd6a8f4fc; no qualification is claimed for either candidate.

Signed Bun repairs through 8a8ab89ef1 fix startup NODE_OPTIONS diagnostics, SQLite publisher-export consumption, data-URL MIME selection, fs-test registration, response-socket cleanup after mutable finish listeners, and absent objects in prototype traversal. Native run 42588256994 passes build, exact engine identity, packaging, Rust trimming-policy tests and all four engine IR regressions against 651eeaca6e27. The full selection now completes: 691 passing / 21 failing records, including two passing dependency-setup records. NODE_OPTIONS, SQLite column types, loader, fs, IPC, main HTTP and fast-path regression files pass. Qualification remains red on the recorded ICU/size/trimming and reflection/fixture failures. Verified report artifact 13661302173: 4,423,747 bytes, SHA-256 b2ebfb65d84edd0ffe1f840a0dd2aa61f762e7d55d0b5e7b974e26448e42c0d5.

Focused replay 42590096312 uses the immutable old aa024 executable, separate from probe ffa6e04cbf. Intentional fatal-init/UV cases now pass in 142/88 ms with original assertions/deadlines after process-local mapped-core suppression; CommonJS plain/AOT parity also passes after retiring the removed layered-test debug route. The overall replay stays red on constructor stack-column parity and an imported namespace-mutation fixture. These findings drive reviewed signed d78fa8ba39 (use the fork's new token position) and 0c10d4cc6e (require TypeError and unchanged imported namespace), without relaxing engine contracts or baselines.

Current signed integration head 56739277f7 includes standard-stream exception propagation, response-owned connection lookup, aliased-response cleanup, native-owner Proxy callback state, and Node-verified cork-count expectations. Corrected signed b47a817a21 applies runtime extension precedence to in-place AOT imports and restores stock compiled/bundled policy; it supersedes the earlier executable-only no-package fallback. Six Rust load rows now exercise both modes. Source checks and formatting pass on this head. Full native run 42603897638 completed with explicit frozen base 2596ac5d391d47804c93a42bdbe615804aa62387 and engine 651eeaca6e2792378928033b1ae7ac66d6f91eab. Build, trimming-policy Rust checks, written-position/module-mode checks and AOT CLI gates pass. The complete run-aot.test.ts file passes 72/72. The ledger records 695 pass / 17 fail plus four separately passing IR inputs across 714 selected paths; direct networking passes 154 tests with eight skips. Remaining failures cover source/system-ICU version, size/locale/loader retention, type optimization and HTTP/prototype surface assertions. Full green and shipping qualification remain incomplete. Verified report 13668566451: 4,423,412 bytes, SHA-256 aedb0b12aa0c0000aa3f60c75e5fb8304191f4078f5a8b2510bb702e913974f7.

Native gate 42599698918 builds and packages exact a6644f3357030f40982c976c3a522a8b0a3af7e5; 256 trimming unit tests, 12 invariants and all six written-position tests pass. The load-format gate then exposes a bad test assumption: its helper defaults to in-place mode, so the earlier CommonJS expectation change cannot follow from the executable-only fallback. CLI and the broader selection did not run. The corrected two-mode test and in-place producer repair are reviewed and signed in b47a817a21. Earlier gate 42597791945 separately stopped at an unused test import, fixed in a6644f3357.

Admitted runtime replay 42603067250 uses immutable native a6644f3357 with the corrected framing helper: all 37 focused HTTP regressions and both standard-stream cases pass. Its three CJS failures use the older executable and are superseded by 56739277f7's complete 72-test CLI pass. Exact response/body/callback assertions remain intact. Verified replay artifact 13666283475: 7,087 bytes, SHA-256 c0dba5ca1ac77068cac6ecc1bccfa74e0044de7deb80c6785cf4e0a5648cf2d4. Upstream CJS #48354 and standard-stream #48352 are ready for review; stock-native Buildkite validation remains pending (#139279, #139274).

Proxy socket red replay 42598563871 proves both new TCP regressions fail on immutable native 8a8ab89ef1b6f75b6daea63c84cc1156b8e4ec94: raw writes lose bytes/close the connection, and uncorking queued response writes throws a private-field error. Reviewed signed f7c57fcac8e8f2ec528e22c7e350b157d23a8ab2 keeps private callback state on the existing native handle's canonical socket owner, while preserving public receiver observations and accounting. Verified red-report artifact 13665045811: 4,882 bytes, SHA-256 8cbfcf6293ab6d47e3520967536be88455812f50c8664686a4a2e17908f6e12b. The later admitted replay above passes both cases, including the corrected raw-prefix framing and all 37 HTTP siblings.

Matched stock comparison 42601831115 succeeds with exact fixtures, one frozen stock type/dependency tree, LLVM 23.1.1, Rust nightly-2026-09-15 and system static ICU 74.2. Stock Bun 2596ac5d391d47804c93a42bdbe615804aa62387 plus stock WebKit 5a61071f79134bf41844e7ea31a8449147d85dd4 removes 110/98 features; candidate a6644f3357 plus engine 651eeaca6e27 removes 109/93. All four compiled programs produce exact expected outputs and clean exits. The simple-server delta is OperationsOnPrivateNames; the unknown-values delta additionally retains OperationsOnArgumentsObjects, OperationsOnDates, OperationsOnEncodedText and OperationsOnStringBuilders. The same 109/93 shortfall persists at 56739277f7. Separate operation-origin diagnosis 42607192709 is running with frozen Bun 56739277f7834a63cdd2ba8fd496672c5ab8f645, controller 2009bdc5775deb66913637fd1892ac1d4e8ee798, and diagnostic-only engine adc737694a84cf1d0ac1c72c4c73adf9a023b107. Both probe patches passed independent review and are signed; the admitted engine candidate remains 651eeaca6e27. Producer diagnosis is in progress; all original floors remain unchanged. Verified comparison artifact 13667171797: 181,108 bytes, SHA-256 05fd59aed00f135df43ba00c721f877d95fefbf7b17fcad70acf0ab32bca6770. This is source-pair proof, not shipping ICU 79.1 qualification; the separately recorded coarse-ICU loader/size/locale gaps remain.

Completed native qualification 42591603139 builds earlier signed 01857e53babc3a5e21b90dd716ff20e33b1f11be with engine 651eeaca6e2792378928033b1ae7ac66d6f91eab: build, packaging, trimming-policy tests, focused Rust positions, and production CLI constructor-stack/namespace checks pass. The full selection completes with 691 passing / 21 failing records. Its remaining CLI failures isolate bare imported .cjs strictness; its three source-map expectations still point at Error instead of the repaired new position. The source-map expectations are repaired in 6bdde38d9a46623a1d7aae59b8195d960b39ceb7; the initial CJS fallback was insufficient and is superseded by the reviewed in-place repair b47a817a21, with native proof pending. Verified report artifact 13663820238: 4,424,942 bytes, SHA-256 7a30e9f015ac31d070a69c321255853ceccec1d7768d67cd21d2662bf4a61163. Partial native run 42595417947 built earlier a2f039d9dd6d75a1ee05caa136acb8b698a58b6d: build, packaging, trimming-policy tests, focused Rust/CLI checks, and the pinned Node control pass; its default selection has 28 passing / 1 failing record (system ICU floor). The frozen-base dispatch input was omitted, so those 29 records do not qualify the standard-stream/HTTP owner repairs. That selection error is corrected in full run 42597791945. Verified partial-report artifact 13664131945: 4,352,034 bytes, SHA-256 00ca30fbf84d5584918b83111c26a46c650c370d9eaa98c551436caef094db1d.

Focused red replay 42594192257 uses immutable executable artifact 13661110892 from native 8a8ab89ef1b6f75b6daea63c84cc1156b8e4ec94: both new repeated-request Proxy/inherited-response tests fail with ERR_HTTP_SOCKET_ASSIGNED; the existing alias-state test fails too. Node declarations 26.2.0 and http.d.ts are present. Verified diagnostic artifact 13663135550: 18,953 bytes, SHA-256 ce4a25070bac4de207bb56932417586e817c6d66bbf1a8bfd7dcbd6897f70cdb.

Original single-file control 42594866158 passes plain/compiled HTTP behavior on the same 8a binary and retains the same five generic answer accesses as the migrated fixture. Source comparison shows the retired report preferred non-generic copies, while supported explain summaries select the worst copy; the metrics are not equivalent. Guard diagnostic 42595783244 also passes runtime parity, but reports four rejoining access guards (one named IncomingMessage), not both expected typed-entry guards. This does not establish the former fast-copy slot-optimization assertion; no compiler metadata patch or blanket expectation relaxation has been made. Its verified artifact 13663381963: 915 bytes, SHA-256 8673687ece380331b8c9a81d4334d75d3209e815df46bdb38fa2d871ebcddb2c.

The generic test-only core suppression port is ready for upstream review in oven-sh/bun#48339, with fork-native evidence disclosed; stock-upstream Buildkite remains blocked. Shipping-archive transport, remaining runtime/trim/reflection qualification, publication approval, and consumer repin remain outstanding.

Signed local engine commit b17472779f04da2779d553ae29c1f598bd36edc0 prepares the candidate pin to Bun aa024e5a1d5466098357784d7f6fb159581e1478, tree d5ef4d4e1575e9afd50c9b13e222eb2226f1dac5. The three-value update passes exact Git-object/adapter-hash checks and fresh independent review scoped-clean P0–P2. It is retained unpushed while canonical release-asset transport remains blocked. Remote PR head and current engine proof remain 651eeaca6e27, candidate 0dd6a8f4fc; neither candidate is qualified.

Fresh reviews are scoped-clean P0–P2 for the full fork delta, namespace/visitor ports, typed-array allocation, harness, Bun repairs/fixtures and this candidate update. Static checks verify the exact candidate tree/manifest and all three adapter input hashes against its Git objects.

Engine proof and remaining work

The following evidence belongs to signed a5f127f226d58fb28332a01c889964c6d408c08b:

  • Native ARM64 qualification passes the exact typed-array AOT allocation case, all five namespace and 17 module-program cases, 1,901 stress and 1,639 module cases, three API regressions, assembler/FFI, five accounting/sampling modes and seven stack modes. Source, complete AOT output and stress/module results were independently checked in artifact 13656560130: 59,594 bytes, SHA-256 89415eea95b15df656b12a5c27cc89f665af4835bcf7b448eea97c2954ce4d10.
  • Engine checks pass both macOS artifact builds, Windows ARM64 build/native runtime, and the Linux engine gate with 1,901 stress/1,639 module cases, four sampling tiers, five array-buffer modes and seven stack modes. Windows passes strict provenance, PE architecture, startup/DFG/FFI and five accounting modes. Both Linux archives build. The Linux job then fails compiling the obsolete parser macro on old candidate 8b48ac2586; the active Bun branch repairs that failure. Independently verified Linux proof 13654679995: 347,970 bytes, SHA-256 00f1b5d2602a949d8e6712b7b24ac41c02504f553fe20d15dd46c4679b50ba03.

Current-head engine checks have two pre-compilation transport failures: Linux exhausts five HTTP 504 retries downloading canonical zstd, and Windows correctly rejects a 92-byte HTML response to its checksum-pinned ICU download. The macOS artifact builds pass on 651eeaca6e27; ARM64 qualification passes on the same source. Independently verified artifact 13658881366 is 59,550 bytes, SHA-256 65a4d4266b29e092d6b50000e31a9e7df0410eacfde10c5c368f1bfa4585ae24: exact typed-array AOT case, five namespace/17 module-program cases, all 1,901 stress/1,639 module results, three API regressions, five accounting/sampling modes and seven stack modes pass. Raw results and AOT output were checked against the gate. The single fresh-runner retry (attempt 2) also fails before compilation: Linux ICU and Windows ASAN downloads return the same HTML-body digest bef140a1a96994029153dca8c00b1750b9a5a764fb9db2dc68d7bb40e8a29e8a. Checksums reject those responses. Automatic retries stop; canonical archive qualification requires working runner-to-release-asset transport. Canonical recipes, source pins and expected checksums are unchanged. Previous proof retains its recorded source identity. Canonical-ICU Bun runtime/size/shipping and current consumer qualification remain incomplete. Source/system-ICU receipts retain shippingArchiveQualified: false; earlier FA/S proof does not qualify this candidate.

Draft. No fork/native code was executed on the maintainer workstation. This branch is admitted only with publish=false. No release, tag, archive publication, consumer repin or deployment is included. Tracking campaign: openclaw/bun#221.

Jarred-Sumner and others added 13 commits October 31, 2026 16:47
…ilds of large functions (oven-sh#967)

* AOT: crashes and wrong answers found since oven-sh#942, and faster builds of large functions

Its tests that need Bun are in the Bun PR that goes with this one.

Crashes of compiled programs:

    let b = null, c = null;
    if (n) c = { k: 1.5 };
    while (b !== b) b = [b];
    if (y != b) { [b, y] = [y, b]; return c === y ? c : 1; }

ended by SIGSEGV, and ten lines of the same kind aborted the compiler. SinkAllocations analyses a function,
counts and then rewrites it, and all three must decide alike. A helper read constants out of the function as
it stood, so the rewriting saw constants that the analysis had not seen. oven-sh#942 mended one of its five callers.
Now the question is answered from a table that is filled before anything is rewritten, and that mend is gone.

    try { null.x } catch (e) { e.constructor.list = { length: 3 } }    // TypeError.list was an array before

ended by a signal, gave `undefined`, or called the function that had been replaced. Flow took the stores that
it could follow for all the stores there are. A store through an object that nobody knows is now looked for on
every built-in class, and on the prototypes above crypto.subtle, Bun.s3 and a request's signal.

    class Holder { held = stream[Symbol.for("nodejs.stream.readable")]; }    // a ReadableStream

aborted, and in a function the read gave `undefined`. A symbol out of Symbol.for() was treated like one out of
Symbol(), which the host cannot reach.

Wrong answers:

  - After `delete A.prototype.twice`, `new A(8).twice()` still answered. With a setter on B.prototype alone,
    `const o = k === 0 ? new A(k) : new B(k); o.y = 5` in a loop ran B's setter for the first A. B3 moved the
    load of a class's guard bits across the allocation that makes the class.
  - `require("./config.json")` in a .cjs file that runs while the graph loads answered the ES namespace.
  - `Object.assign({}, source)` stored names before symbols for a source with room for elements.
  - Closures of one function that call each other in tail position: a stack frame had the name of the
    function object that was called, not of the one that ran.
  - With one optional pass off, `o.a` was folded where `o` may be null, and another pass aborted the build.
  - Two runs of one executable made different caching decisions: a table was hashed by an address.

Memory: the slow path of a stub has a frame as large as what it saves. Objects were kept alive longer than in
plain Bun. A store of "" or of a string of one Latin-1 character needs no write barrier.

Build time. A generated function of 1,000 statements builds in 7,891 M instructions, from 12,473 M, with the
same output: liveness gave up only after a fixed number of visits and then started over, a dataflow kept a
counter for each condition in each block, and the guards' analysis asked each write about each proof, where
4,304 writes had 28 different answers.

Speed: `a[i] === b[j]`, case conversion sixteen characters at a step, a read by name of a slot that holds a
raw double, and 226 stepped benchmark rows through the stubs' new form.

Checks: the proof checks compare a function's identity and are no longer skipped in forwarding code.
`--aot-check=ClaimsOfFlow` tests every claim of flow where it is made. Under the verifying flags
SinkAllocations checks that its three steps decided alike.

* AOT: built-ins reached by computed names, RegExp fixes, a vectorizer crash

Crashes

- `Bun.gzipSync.list = [1, 2]; Bun[JSON.parse('"gzipSync"')].list = { length: 3 }`
  and then `Bun.gzipSync.list.length` segfaulted. So did the same through
  `Event.prototype[name]`, names out of `Object.keys(Bun)`, and
  `Bun.Glob.prototype` reached by three computed names.
  `Object.setPrototypeOf(Object.getPrototypeOf(Bun.s3), { .. })` was not seen.
  A read under a computed key, or of `prototype`, off an unknown object in the
  program's own code now reaches the host prototype objects. This replaces the
  wider rule of the previous commit, which also counted such reads in library
  code and cost `await request.json()` its typed parse.
- The compiler died with "Floating point error" on
  `while (a == 65536 && i0 < 9) { i0++; c = c > 0 ? d : c; }`.
  B3VectorizeLoops divided by the number of memory accesses of a loop that has
  none.
- A loop counter beyond int32, read from a property and used to index a typed
  array, trapped.
- `RegExp::matchWithImageCode` dereferenced a null image record when jsc runs
  its tests with regular expressions compiled ahead of time (six JSTests).

Wrong answers

- `/^(?=(.*))\1$/` said "no match" for a subject with characters outside
  Latin-1. The pattern was taken to consume 8-bit characters only: what a
  lookahead captures counts once a back reference can consume it.
- `new RegExp("\\B" + text, "u")`: `\B` matched inside a surrogate pair.
- `function make(k) { return k === 0 ? new A(0) : new B(1) }` with a getter on
  `B.prototype` alone: `make(0).size` ran `B`'s getter when the first `A` was
  made behind a test of both classes.
- `x.f += n` where `f` starts on the prototype: the arm that reads `f` by name
  may run a getter, and came back into code that relied on a guard from before
  the read.
- `Interface.prototype[Symbol.asyncIterator]` read in a function was a
  different function object than `Reflect.get()` returned (node:readline).
- `await import("sass")` in an executable threw "Cannot assign to
  Function.prototype.call$0". Programs out of dart2js add such names.
- `function twice(f, n) { return f(f(n)) } twice({}, 1)` quoted `f` instead of
  `f(n)` in the error message.
- `import * as ns`; `Reflect.setPrototypeOf(ns, ..)`, `Object.freeze(ns)`,
  `"added" in ns`: a guard for compiled objects read a module namespace.

Windows

- `hasChanged |= std::exchange(member, copyOfClass(member)) != member` compares
  the old value with itself where the right operand is evaluated first, as on
  both Windows targets. Copied classes and closure factories kept the types of
  the original there: correct, but less precise.

Memory

- `for (let i = 0; i < n; i++) a.push(f(i))` reserved the whole array up front
  even where `f` may throw and end the loop.

Faster

- `let current = first; while (current) current = current.run(this)` with
  `first` typed by an interface: objects that have the interface's members but
  none of its layouts stay in the typed loop. Effect's run loop: -20%
  instructions per turn.

Smaller

- The compiler's rarely run files are built for size: -600 KB.

Tools

- The map and `--aot-report` say "proven" or "missed optimization" where the
  final IR knows the receiver's class, instead of "unknown".
- False alarms under `--aot-validate` and `--aot-verify-each-pass`: a field
  that holds its own object, what an `await` holds, `Object.keys()` of an
  object with a computed key.

* AOT: FlowSiteLevel stays within 24 bytes on Windows

The previous commit added a bool at the end of FlowSiteLevel. With the
Microsoft ABI the two bit-fields at its start take a unit of their own, so the
struct was already 24 bytes there and grew to 28, and the static_assert failed
every Windows build. The bool now stands behind the two uint8_t members, in
what was padding on every target.

* AOT: a build aborted where a generic copy rejoins at a block entered by a test's own edge

`bun test --aot` on NestJS's suite stopped with "Stopped while compiling
printMessages .. in PlaceTypeTests". A block's parameters are its explicit
arguments followed by the results of the edges that enter it, such as the
narrowed value of a type test. Two places indexed an edge's arguments with a
parameter's index, which is out of bounds for an edge result. Both now ask
incomingValueOf(). An edge's own result counts as proven when a rejoin is
planned, and as unknown when the first values of loop variables are looked for.
The second commit of this pull request brought this.

* AOT: the first error in a long statement, and the memory of a build with a long chain of classes

Two fixes for two red tests of oven-sh/bun#47571.

The first error at a place costs the same in a longer file

Forty places inside one `switch` of 12,000 cases each throw their first
TypeError ("undefined is not an object (evaluating 'a.b')"). To quote the source
in such a message the run time decodes the entries that say what was printed in
place of the original text. It decoded every entry of the kept piece of source
at each first error, and a long statement or function is one piece. The entries
of a piece are now decoded once and kept, however many places in it throw. A
compiled test run decoded every entry of the module each time: now once.

The long file decodes 2,162 entries where it decoded about 357,000. Forty places
in one statement: 2.3 > 1.5 ms. In a test run: 4.05 > 0.59 ms. With
AddressSanitizer it was 130 to 141 ms against 2 to 3 ms in the short file, which
is what failed the-first-error-at-a-place-costs-the-same-in-a-longer-file on the
x64 ASAN lane. No message changes. The counts file has a new line,
`decoded:TextPrintedInPlace`.

A build keeps the partition of a call's receivers as words

`function ask_i(x) { return x.weigh() + ask_(i-1)(x) }`, 800 in a chain, each
given an instance of one class more. No two calls of `weigh` see the same
classes, so the cache kept one partition per call and key, each with an arm per
class: 320,000 arms of 112 bytes. The cache now keeps a partition packed: 24
bytes for an arm with one method and one layout. And "may this call enter a
table look-up" built and kept a whole partition to answer one bool: it now asks
class by class, stops at the first no and keeps nothing.

800 classes: 189 > 166 MB, 20.14 > 20.01 G instructions. The generated code is
identical on 1.16 million functions. build-scaling-4 failed on macOS arm64 with
"twice as many classes cost 2.58 times the peakBytes; allowed: 2.5". On Linux
that ratio goes from 2.29 to 1.85. Not measured on macOS.
… never ended, faster loops (oven-sh#971)

* AOT: miscompilations and crashes found since oven-sh#967, builds that never ended, faster loops

Wrong answers of compiled programs:

- A list of numbers with one `undefined` in it, iterated by two loops. The first adds
  the numbers up, the second counts the `undefined`s: it counted 0 instead of 1.
- In a generator, a value read before a `yield*` and used after it was wiped when a
  parameter that held an object was set to `null` or `undefined` in the same loop: 12
  instead of 22. A second program never ended.
- A `RegExp` made from text out of a list was compiled from the text the build had
  predicted, even when the list was read under two names in one step and then changed.
- `main.mjs` imports `m.mjs`, which imports `x.cjs`, which calls `require()` on `m.mjs`
  under a name made at run time: `main.mjs` ran after `x.cjs` had ended, not before the
  `require()` returned.
- An `import()` made while other `import()` calls were waiting, and whose graph shares a
  module with one of them, was held back behind all of them.

Crashes of compiled programs:

- A segfault in eleven lines: a loop reads and stores a static field that holds an
  object, after the field was deleted while a Proxy was on the class's prototype chain
  and was defined again through the trap.
- A segfault at address 0 after an out-of-memory error that the program catches: a rope
  of 2^30 two-byte characters that cannot be flattened, ahead of a short loop in a `try`
  with `catch` and `finally`.

Builds that failed or never ended:

- Thirteen lines did not build in two minutes: two nested loops of eight iterations, a
  swap in a `try`, an xor in its `finally`. B3's `Value::returnsBool()` recursed into both
  operands without remembering what it had asked, so its cost was exponential.
- One function spent 214 of 246 seconds in type propagation: its queue was last in,
  first out.
- The compiler aborted on `for (;;) { if (source.take === never) return ..; const got =
  source.take(..); .. }`. A loop that reads the same property of an unchanging object on
  every iteration gets a version that asks ahead of the loop, and a type test on that read
  was turned into a cast of the copy. Where both sides of the test's branch leave the
  loop, the branch still hands on what the test proved, so its condition has to stay a
  test.
- Fourteen lines stopped the build with `InvalidGuard`: a read of a typed array at the
  top of an iteration relied on the bounds check at the end of the previous one, and the
  loop's counter was then replaced by a constant.
- Quadratic time in large functions: three places in Air's register and stack
  allocators, two in the ahead-of-time compiler's own passes (one is flow analysis), and the
  lookup of a regular expression's symbols (arm64: twice as many alternatives cost 9.5
  times as much, now 1.74 times).

`bun test --aot`, following oven-sh/bun#44833:

- An `import` that reaches a mock whose factory threw gets the error that the loader
  kept. `require()` of a mocked module returns what the factory returned. A later mock
  of a CommonJS file doesn't change what an earlier `require()` returned.
- The engine's own tests no longer depend on how many built-ins Bun has.

Speed:

- New B3 pass, promoteLoopMemory: `a[k] += v[j]` and `o.total += x` reloaded on every
  iteration what the previous one had stored. The word is read once ahead of the loop
  and carried in a Phi. The stores stay where they are. Off by default; only the ahead-of-time
  compiler's policy turns it on.
- `map.has(k)` followed by `map.get(k)` searches once. Keys that are objects are searched
  inline in loops.
- A generator function made for each call: 2,585 to 175 instructions. tslib's
  `__awaiter`: 3,876 to 1,441 per iteration.
- Helpers that Babel and TypeScript emit: `Reflect.construct` behind tests, a built-in
  bound and called in one function, descriptors read and defined again, `for..in` copies.
- Remainders and quotients of whole numbers stay integers. A loop polls with one
  faulting load on arm64, macOS x64 and Windows arm64 too.

* AOT: a library function that a test run leaves out is refused, not aborted on

`import { test, vi } from "vitest"; test("t", () => { vi.useFakeTimers(); })` under
`bun test --aot` ended in `abort()`. The code that throws "was not compiled into this
executable" looked the function up in the table of built-ins to ask whether it is an
accessor's getter, and a function that the table leaves out has no record there. It asks
`contains()` first now, so the error is thrown.

* AOT: a member copied off `require("bun")` under a computed key is followed to its call

`bun = require("bun"); copy = {}; copy[key] = bun[key]; copy.plugin(options)`: the build
now sees that `copy.plugin` may be `Bun.plugin`. The test, `plugin-copy-late-mark.ir`,
comes with Bun's half.

* AOT: two segfaults: a store through a caught error's `constructor.prototype`, and to a method found on `Bun.s3`

`TypeError.prototype.list = [1, 2]`, then `catch (e) { put(e.constructor.prototype, { length: 3 }) }`
with `put(where, what) { where.list = what }`, then `TypeError.prototype.list.length` read in
a function: the read took the list for what the build had seen stored by name, and the
program ended in a segfault. The same with `Bun.S3Client.prototype.file.list = [1, 2];
Bun.s3.file.list = { length: 3 }`. Where no list was involved, the read answered
`undefined`. Both stores are now seen by a read that names the object.

* AOT: promoteLoopMemory is not switched on yet

The pass and its tests stay in B3. The ahead-of-time compiler's policy no longer turns
it on.

What broke, in a loop:

    holder.n = (holder.n + 1) | 0;
    if (j === when) other.n = 50;
    if (holder instanceof Other) bump(holder);

with `function bump(o: Other) { o.n = (o.n + o.k) | 0 }`. Where `holder` and `other` are
one object, a `Plain`, the store of 50 was lost: the function answered 7:29 instead of
55:317. The copy of `bump` in the loop never runs for that object, but its access named a
narrower heap for the word, and the pass let that one heap decide that nobody else
writes it.
…ex slots, a bounds test on split() (oven-sh#972)

* AOT: miscompilations and crashes found since oven-sh#967, builds that never ended, faster loops

Wrong answers of compiled programs:

- A list of numbers with one `undefined` in it, iterated by two loops. The first adds
  the numbers up, the second counts the `undefined`s: it counted 0 instead of 1.
- In a generator, a value read before a `yield*` and used after it was wiped when a
  parameter that held an object was set to `null` or `undefined` in the same loop: 12
  instead of 22. A second program never ended.
- A `RegExp` made from text out of a list was compiled from the text the build had
  predicted, even when the list was read under two names in one step and then changed.
- `main.mjs` imports `m.mjs`, which imports `x.cjs`, which calls `require()` on `m.mjs`
  under a name made at run time: `main.mjs` ran after `x.cjs` had ended, not before the
  `require()` returned.
- An `import()` made while other `import()` calls were waiting, and whose graph shares a
  module with one of them, was held back behind all of them.

Crashes of compiled programs:

- A segfault in eleven lines: a loop reads and stores a static field that holds an
  object, after the field was deleted while a Proxy was on the class's prototype chain
  and was defined again through the trap.
- A segfault at address 0 after an out-of-memory error that the program catches: a rope
  of 2^30 two-byte characters that cannot be flattened, ahead of a short loop in a `try`
  with `catch` and `finally`.

Builds that failed or never ended:

- Thirteen lines did not build in two minutes: two nested loops of eight iterations, a
  swap in a `try`, an xor in its `finally`. B3's `Value::returnsBool()` recursed into both
  operands without remembering what it had asked, so its cost was exponential.
- One function spent 214 of 246 seconds in type propagation: its queue was last in,
  first out.
- The compiler aborted on `for (;;) { if (source.take === never) return ..; const got =
  source.take(..); .. }`. A loop that reads the same property of an unchanging object on
  every iteration gets a version that asks ahead of the loop, and a type test on that read
  was turned into a cast of the copy. Where both sides of the test's branch leave the
  loop, the branch still hands on what the test proved, so its condition has to stay a
  test.
- Fourteen lines stopped the build with `InvalidGuard`: a read of a typed array at the
  top of an iteration relied on the bounds check at the end of the previous one, and the
  loop's counter was then replaced by a constant.
- Quadratic time in large functions: three places in Air's register and stack
  allocators, two in the ahead-of-time compiler's own passes (one is flow analysis), and the
  lookup of a regular expression's symbols (arm64: twice as many alternatives cost 9.5
  times as much, now 1.74 times).

`bun test --aot`, following oven-sh/bun#44833:

- An `import` that reaches a mock whose factory threw gets the error that the loader
  kept. `require()` of a mocked module returns what the factory returned. A later mock
  of a CommonJS file doesn't change what an earlier `require()` returned.
- The engine's own tests no longer depend on how many built-ins Bun has.

Speed:

- New B3 pass, promoteLoopMemory: `a[k] += v[j]` and `o.total += x` reloaded on every
  iteration what the previous one had stored. The word is read once ahead of the loop
  and carried in a Phi. The stores stay where they are. Off by default; only the ahead-of-time
  compiler's policy turns it on.
- `map.has(k)` followed by `map.get(k)` searches once. Keys that are objects are searched
  inline in loops.
- A generator function made for each call: 2,585 to 175 instructions. tslib's
  `__awaiter`: 3,876 to 1,441 per iteration.
- Helpers that Babel and TypeScript emit: `Reflect.construct` behind tests, a built-in
  bound and called in one function, descriptors read and defined again, `for..in` copies.
- Remainders and quotients of whole numbers stay integers. A loop polls with one
  faulting load on arm64, macOS x64 and Windows arm64 too.

* AOT: a library function that a test run leaves out is refused, not aborted on

`import { test, vi } from "vitest"; test("t", () => { vi.useFakeTimers(); })` under
`bun test --aot` ended in `abort()`. The code that throws "was not compiled into this
executable" looked the function up in the table of built-ins to ask whether it is an
accessor's getter, and a function that the table leaves out has no record there. It asks
`contains()` first now, so the error is thrown.

* AOT: a member copied off `require("bun")` under a computed key is followed to its call

`bun = require("bun"); copy = {}; copy[key] = bun[key]; copy.plugin(options)`: the build
now sees that `copy.plugin` may be `Bun.plugin`. The test, `plugin-copy-late-mark.ir`,
comes with Bun's half.

* AOT: two segfaults: a store through a caught error's `constructor.prototype`, and to a method found on `Bun.s3`

`TypeError.prototype.list = [1, 2]`, then `catch (e) { put(e.constructor.prototype, { length: 3 }) }`
with `put(where, what) { where.list = what }`, then `TypeError.prototype.list.length` read in
a function: the read took the list for what the build had seen stored by name, and the
program ended in a segfault. The same with `Bun.S3Client.prototype.file.list = [1, 2];
Bun.s3.file.list = { length: 3 }`. Where no list was involved, the read answered
`undefined`. Both stores are now seen by a read that names the object.

* AOT: promoteLoopMemory is not switched on yet

The pass and its tests stay in B3. The ahead-of-time compiler's policy no longer turns
it on.

What broke, in a loop:

    holder.n = (holder.n + 1) | 0;
    if (j === when) other.n = 50;
    if (holder instanceof Other) bump(holder);

with `function bump(o: Other) { o.n = (o.n + o.k) | 0 }`. Where `holder` and `other` are
one object, a `Plain`, the store of 50 was lost: the function answered 7:29 instead of
55:317. The copy of `bump` in the loop never runs for that object, but its access named a
narrower heap for the word, and the pass let that one heap decide that nobody else
writes it.

* AOT: fix crashes and miscompilations found since oven-sh#971, free Map/Set index slots, turn promoteLoopMemory back on

Stacked on oven-sh#971. The stored programs and tests for everything listed here come with oven-sh/bun#47605.

Crashes and failed builds:

- `TypeError.list = [1, 2]; JSON.parse("0", () => Reflect.set)(e.constructor, "list", { length: 3 })`
  with `e` a caught error, then `TypeError.list.length` in a function: the compiled program
  segfaulted. The same happened with a hidden `Object.assign` or `Object.defineProperty`, and when
  the writer was called as a member of a hidden object. A write through a value the compiler can't
  identify is now also applied to built-in objects, even when flow analysis sees no path to them.
- `Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key))` with a
  `key` object whose `toString()` returns "a" and then "b": plain prints 3, compiled code
  segfaulted. With methods the wrong one ran; with getters it threw "'a' was left out of the
  executable".
- Every `--aot` executable aborted before its first statement on a kernel with 64 KB pages
  (RHEL 8 aarch64, Oracle's UEK, the 64k kernels for NVIDIA Grace).
- The compiler aborted with "Stopped while compiling run in ConvertCountersToIntegers" on
  `for (..) { if (j === w) other.n = j; holder.n = (holder.n + 1) | 0; if (holder instanceof Q) bump(holder); }`.
- `vi.doUnmock("./k.js")` while a plugin's async `onLoad` is still loading another import
  segfaulted under `bun test --aot`.
- `bun test --aot` aborted under `validateExceptionChecks`, which CI's ASAN lane sets, when a mock was
  installed in a layered run:
  `vi.doMock("./m08.js", async () => { await sleep(80); return { value: "mocked" }; }); import("./m08.js")`.

Miscompilations:

- The code that creates, fills and stores a module variable's value is deferred until the variable
  is first read. An assignment to a plain object or function created by that initializer was
  deferred with it. But a program may call `Object.freeze(Object.prototype)` or
  `Object.defineProperty(Object.prototype, "toString", { writable: false })`, and after that an
  assignment to an inherited name fails: a TypeError in strict code, silently dropped in sloppy
  code. Imports run first and the main module hardens afterwards, so plain did the store before the
  freeze and compiled code did it after. main has this bug too.
- A loop's stores to a variable were delayed to the loop's exit edges, even across an operation
  that throws only when memory runs out (`text.charCodeAt()` on a rope). That error can be caught,
  and then the loop is left through none of those edges.
- A Map or Set lookup with the same key on every iteration was hoisted out of the loop, even when a
  `try` covered the lookup but not the loop's preheader, and even when the loop might not run:
  `for (let i = 0; i < 0; i++) map.has(rope)` threw a RangeError.
- A loop that does `const list = []`, pushes, reads `this.state.type`, reads `list[0]` and stores the
  list into a node at the end of the iteration: a value read back out of an open object was taken
  for this iteration's list. Also with the push on one arm of an `if`.
- `seen.push([a])` in one loop and `for (const kept of seen) show(kept)` in the next: the inner
  list was attributed to `show()`.
- `const o = Object.create(Blob.prototype, {}); o.constructor = { get name() { return "Stored" } }; o.text()`:
  plain throws ERR_INVALID_THIS ".. received an instance of Stored"; compiled code threw "'name' was
  left out of the executable". The same for `Buffer.concat(v)` when `v` is an object that isn't an array.
- `const { module } = await WebAssembly.instantiate(..)`: the compiler didn't know what the promise resolves with.

Modules:

- `for (3 times) try { require("./t.cjs") } catch {}` where t.cjs throws: the body ran once and the
  first error was thrown three times. It now runs again each time, as in node and `bun run`.
- `Object.isExtensible(require("./e3.mjs"))` after an import of the same file: plain true, compiled false.
- `require("./m3.mjs"); Object.keys(require("./d.json"))` where m3.mjs imports d.json: plain `a,default`, compiled `a`.
- Loading a file that only a plugin can provide, under a name computed at run time.
- A test registers `Bun.plugin` with an `onLoad` that matches slow.js and then does `await import("./user.js")`,
  where user.js imports k.js and slow.js: "Cannot access 'x' before initialization" for k.js's export.

Quadratic behavior:

- `map.delete(k); map.set(k, v)` took a new slot in the table's index each time and never freed the
  old one, so each iteration cost the size of the table. A deletion now frees the slot when no
  search can miss it. This costs 5 more instructions on a set and on a delete.
- `class Below extends mix(Base)`: the whole caller was walked for every such call. At 3,200 classes
  that step went from 8,306.6 M instructions to 119.7 M; the generated code is byte-identical.
- Two more build steps that grew with the square of the program: choosing representations
  around a web of values, and finding who reads a parameter that is only passed on.

Speed:

- The AOT policy turns promoteLoopMemory on again, with the fix for the aliased store that got it
  turned off in oven-sh#971. What guards it: 14 stored programs that each gave a wrong answer with an
  earlier version of the pass, a fuzzer family written for it, 8,815 programs with no differing
  result, and a review by someone who didn't write it and tried to break it: 0 of 7,728 programs wrong.
- The low word of a sum that was built from doubles is computed as a 32-bit sum.

Outside aot/:

13 files. The JIT compiles b3/ too; the changes below run there only where noted.

- b3/B3PromoteLoopMemory.cpp and its testb3 cases: the pass. It runs only when
  `loops.promotesMemory` is set: false by default, set only by the AOT policy.
- b3/B3LikelyPaths.{h,cpp}: how the nearest common dominator over likely paths is found. Used by
  hoistLoopInvariantValues() under `loops.hoistsOnlyFromLikelyPaths`: false by default, set only by the AOT policy.
- b3/B3ReduceStrength.cpp and testb3_bun_reductions.cpp: `Trunc(Op(a, b))` becomes
  `Op(Trunc(a), Trunc(b))` when this walk built the operation from doubles. Under
  `narrowsIntegers`: false by default, set only by the AOT policy.
- b3/B3LoopRangeChecks.cpp, b3/B3Policy.h: a switch that lets a test sabotage the compiler
  (`omitsLimitOfClampedBound`, false by default) and a client callback (null by default).
  Loops are versioned only under `loops.versions`: set only by the AOT policy.
- b3/B3CompilationReport.h: 16 more counters in a Procedure's report. That is 64 more bytes per
  Procedure, in the JIT too; nothing there increments them.
- heap/HeapSubspaceTypes.h: an #include under the existing `#if ENABLE(AOT)`, for the
  generators' own subspace.
- llint/LLIntEntrypoint.cpp, runtime/VM.cpp: inside `#if ENABLE(AOT)`: code that runs in the
  interpreter is also counted in a process without an image, under an option that tests set.
- runtime/ExceptionHelpers.cpp: inside `#if ENABLE(AOT)`: a clearer error for a global function
  declaration that reuses the name of a global that compiled code treats as a constant.

* AOT: a bounds test on the result of split() or splice() compared against the wrong length

    function f(h: string | null): string[] {
      if (h == null) return [];
      const accepted: { type: string; count: number }[] = [];
      for (const part of h.split(",")) {
        const [type, ...params] = part.split(";").map(v => v.trim());
        accepted.push({ type, count: params.length });
      }
      return accepted.map(e => e.type);
    }

Built with --aot-validate, f("a/b") and f("c/d, e/f") returned [] instead of ["a/b"] and
["c/d", "e/f"]: the whole for-of loop was removed. No error, exit code 0. main has this bug too.

When only the first few elements and the length of an array returned by split, match, exec or splice
are used, allocation sinking never builds the array. It becomes a virtual object whose shape counts
only the elements that are kept separately. evaluateBoundsTest() compared an index against that
count as if it were the array's length. Nothing in this function reads a constant index, so the
count was 0, every index was "out of bounds", the edge into the loop body was dead, and the body
held the only use that would have asked for the real array.

For such an array, an index past the shape's count is now unknown instead of false.

The wrong answer has only been seen under --aot-validate, where a type check keeps the array alive.
At default flags, iterating over split()'s result becomes a loop over indexOf and substring and no
array is made. But the rule itself was reached at default flags too, so a wrong answer there can't
be ruled out for earlier builds.

The same shape with splice() was wrong as well. The generated code of ten servers and the
TypeScript compiler benchmark is unchanged at default flags. The tests come with oven-sh/bun#47605:
test/aot/parallel/strings/split-list-walked.ts and test/aot/parallel/arrays/spliced-list-walked.ts.

* AOT: include what AOTValueFlowSolveTestCommands.cpp uses

The file uses StringPrintStream and makeString() without including their headers. It compiled only
where the unified build put it next to a file that does. The -aot lanes failed with "unknown type
name 'StringPrintStream'" and "use of undeclared identifier 'makeString'".

* AOT: don't name a variable `small` in AOTValueFlowCoreTests.cpp

The Windows SDK's rpcndr.h has `#define small char`, so `ValueSets small(1u << 10);` didn't compile
on the Windows -aot lanes ("cannot combine with previous 'type-name' declaration specifier").

* AOT: a module whose mock ended before its body ran has not begun to load

Under `bun test --aot`, two test files each mock the same ES module before it loads
(`vi.mock("./dep.js", ..)` hoisted, or `mock.module()` in a test ahead of the `import()`). A third
file, which mocks nothing, read the second file's mock, by name and through the namespace object,
and dep.js never ran. Plain `bun test` runs dep.js and reads the real values.

When the first mock ended, its module still counted as having begun to load, because that goes by
the group it was loaded with, which is never taken back. So the second mock's factory didn't wait for
the first import. It ran at once, and its values were laid by name over a module whose body had
never run.

Modules::hasBegunToLoad() now answers no for such a module. The bit it reads is set only where a
mock that stood in place of a module ends, so an executable never gets here. The test comes with
oven-sh/bun#47605: test/aot/mock-second-file.test.ts.

* AOT: check for an exception after a mock in place is taken back

AOT::didEndMock() had no throw scope, and went on after setMockInPlace(null), which can throw. Under
`validateExceptionChecks`, which CI's ASAN lane sets, `bun test --aot` aborted in two test files:
"setMockInPlace @ AOTModules.cpp .. unchecked as of captureExports @ AOTModuleLinking.cpp".

    // a.test.js
    vi.mock("./dep.js", () => ({ value: "mock" }));
    // the mock ends with its test file; b.test.js then imports ./dep.js

* AOT: build the same program at one thread as at many

The `typescript` package built at `--aot-threads=1` and at 4 gave two different executables from the
same front-end output. One line in one function of 16,981 differed: for one property read, the
predicted receivers were empty at one thread and listed at two or more. No proof differed, and 4, 4
again and 16 threads agreed, so it was never run to run.

findOnAllThreadsAndDo(), in the pass that computes predictions after the solver's rounds, was the only
place in the flow analysis with a test for exactly one thread. With one worker each item of a wave
ran in place and saw what the items before it had done. With more, all steps of a batch are
computed from the state at its start and replayed in order. Both end at a fixpoint, but the pass has
caps, so not always at the same one.

One thread now takes the same path as many. Batch and share sizes don't depend on the thread count.
At two or more threads nothing changes. Six thread counts from 1 to 32, eight times each: one hash,
the one that 4 and 16 threads gave before. test/aot/same-program-however-the-threads-fall.test.ts in
oven-sh/bun covers it.

* AOT: a read copied for another kind of array storage kept its proof across a store through a second name

    function clean(src, dst, n) {
      for (let i = 0; i < n; i++) {
        if (src[i] < 0) dst[i] = NaN; // a bad sample
        else dst[i] = src[i] * 2;
      }
    }
    clean("1,2,3,4,5,6".split(","), [], 6);
    const samples = [1.5, -1.5, 2.5, 3.5, 4.5, 6.5];
    clean(samples, samples, 6);
    console.log(samples.join(" "));   // 3 NaN 5.5 7 9 13, should be 3 NaN 5 7 9 13

Silent, at default flags, in plain JavaScript and in TypeScript. main has this bug.

PlanArrayCapacities copies the reads behind a test of an array's kind of storage for the other kind,
as far as the test's proof goes. addReadsOfOtherStorage() copied the stores between those reads with
them and never asked whether the copy's proof outlives such a store. A store through another operand
that may be the same array ends it.

The guards are now asked again behind each copy, and a copy that may lose its proof is taken back.
New: --aot-sabotage=CopiedReadsKeepTheirProof, the statistics ReadsCopiedForOtherStorage and
CopiesOfReadsTakenBack, two IR tests. The 30 stored programs come with oven-sh/bun#47605.

* AOT: SplitBehindEntryChecks kept value ids across a retyping that renumbers the values

    function outer(p: any, parent: number | null): string {
      const head = parent === null ? "" : "<a " + parent + ">" + "<b " + parent + ">";
      return head + (p as Kind).name;
    }
    // called hot as outer(given, null)

An assertion build of the compiler aborted on `id.index() < values.size()`. A release build read
outside the function's table of values. No release build has been seen to give other code.

typeValuesFromNever() may cut dead blocks, and then it compacts the function and gives every value a
new id. sayWhatOperandsOfFormerChecksHaveProven() went on with the ids it had taken before. The
retyping is now handed a Renumbering: the checks' ids are mapped, and those cut with the dead code
are dropped. The bound at the head of that function is a RELEASE_ASSERT.

* AOT: the second import() of a CommonJS file whose mock factory throws asks the factory again

    mock.module("./lib.cjs", () => { throw new Error("boom " + ++n); });
    // import(), require(), import(), require(), each caught

Under `bun test --aot` as one program the errors read boom 1, 2, 1, 3. Plain `bun test` has 1, 2, 3, 4.

An import() of a CommonJS file begins at the file's ES face. The walk then comes to the file itself,
which isn't the root, so the throw counted as "behind an import statement" and the error was kept on
the file for the loader. The file behind the root's face now counts as the root.

* AOT: a mock factory that takes importOriginal and fails is asked again at the next import

In plain `bun test` a factory that takes `importOriginal`, sync or async, is laid over the original.
Where it fails the loader keeps no record: the next import asks it again, and the module that imports
the mocked one then loads. A factory without the parameter keeps its error. Compiled code kept the
error for both kinds.

deferMock() is now told which kind the mock is, and runMocksBelow() keeps no error for the first kind.
Where such a factory's promise rejects a turn later, the mock waits for the next load again instead of
being taken away. The test comes with oven-sh/bun#47605: test/aot/mock-factory-retry.test.ts.

* AOT: vi.doUnmock() in a test, behind a hoisted vi.mock() of a module that never ran

    vi.mock("./dep.js", () => ({ value: "mock", fn() { return "mock-fn"; } }));
    import { value, fn } from "./dep.js";
    test("t", () => { vi.doUnmock("./dep.js"); fn(); value; });

Under `bun test --aot` the imported function answered `real-fn` silently, and consts, `ns.value` and
`Object.keys(ns)` threw "before initialization". In plain `bun test` whoever was linked keeps the mock.

An ended mock that stood in place of a module is now let go when a load next comes to that module.
At the end of the test file, while a graph is being loaded, and for .cjs and library modules it is let
go at once, as before. So it is where a module that a require() has already answered imports the mocked
module: a compiled require() of a module that has run asks nobody, so no load would ever come by.

* AOT: `export * from "<a CommonJS package>"` in a mocked module, in layered test runs

    // lib.mjs
    export * from "driver"; export let v = 1;
    // a.test.js
    mock.module("./lib.mjs", () => ({ v: "mock v" })); await import("./lib.mjs");

In a layered `bun test --aot` run (`--parallel=2 --aot-memory-limit=1KB` is enough) this failed with
`TypeError: The module ".../driver/index.js" is not loaded`. The same error came in a second test file
that only imports a user of a module which the first file had mocked. A regression of this branch.

Three places went behind the `export *` of a mocked module to take names, and
evaluateModulesOwedBelow() ran a module that a mock had kept from running without asking the loader for
what only that module imports. A mock that came ahead of the load now stands for the whole module.

* AOT: the first require() of an ES module gave its namespace object a Structure shared with others

    import { x } from "./a.mjs";                       // read hot
    const all = ["./a.mjs", "./b.mjs", "./c.mjs"].map(p => import.meta.require(p));
    function readX(ns) { return ns.x; }                // over the three objects, hot

In a layered `bun test --aot` run readX() came to answer a's x for b. Silent. A regression of this
branch, found in review.

willRequireESModule() set the Structure that all extensible namespace objects share, also on an object
that had a Structure of its own, and hasOwnStructure() went on answering true. A property cache keyed
on the shared Structure then carried the first module's binding to the next. Such an object now gets a
new extensible Structure of its own.

* AOT: the compiler aborted on `o.self = o` where o may be a subclass of Map

    class C extends Map {}
    function see(o) { return o.self; }
    function run(o = new C()) { see(o); o.self = o; }
    run({}); run();

"Stopped while compiling run in PlaceTypeTests." Also over Set, WeakMap, WeakSet, Array and Error.
main has this bug.

Behind a store's tests, rewriteTestedPropertyAccess() takes the last TypeTest for the test of the stored
value, which says nothing about the receiver, and leaves it out. Here the stored value is the
receiver, so its only test was left out and the access couldn't be resolved. The test is now left out
only where the receiver hasn't passed it too.

* AOT: an import() waits for the async factory of a mock below it

    vi.mock("./a", async importOriginal => ({ ...(await importOriginal()), a: "mocked-a" }));
    import { a } from "./a";      // and user.ts: export const atLoad = a;

Under `bun test --aot` as one program: "Cannot access 'a' before initialization", or the real value,
and the next test file "never finished loading". Which of the three came went by when a thread had read
the original from disk. A hoisted vi.mock() turns the test file's import statements into such import()
calls, so Vitest's commonest partial mock met it. main has this bug.

startImport() called the waiting mock's factory, held the import for one turn and delivered it whatever
the factory had done by then. Only the loader's own fetch waited. Where factories wait, the import
now goes on behind them, and is rejected with what one of them throws.

* AOT: a bounds test on the kept prefix of split()'s result compares against the real length

Follows "a bounds test on the result of split() or splice() compared against the wrong length". That
commit made an index past the kept elements unknown instead of false. The other side had the same
flaw: an index inside the shape's count was taken for in bounds, though the array may be shorter than
the number of elements that the function reads.

The test becomes `position < the array's real length`. New: --aot-sabotage=ListsOfBuiltinsEndWithWhatIsKept
and the statistics ListsOfBuiltinsNeverBuilt and ObjectsOfBuiltinsNeverBuilt. It costs 0.15% on one
router idiom.

* AOT: three IR tests check the new counters of arrays and objects that are never built

* AOT: a ring of `export *` with a package in it hung the link of a layered test run

    // index.ts: export * from "./a"; export * from "./b"; export * from "pkg";
    // a.ts, b.ts: export * from "./index";
    import { missing } from "./index";

In a layered `bun test --aot` run the link never ended (485,000 frames when it was killed). It should
throw the SyntaxError for the missing export, as it does as one program and in an executable. A
regression of this branch, found in review.

Modules::isMockedInItsImage() called itself for every dynamic `export *` with no set of visited modules.
It is one loop with a BitVector now, and asks each module once.

* AOT: a name that a barrel hands on from a mocked CommonJS file is the mock's

    // barrel.js: export { name } from "./lib.cjs";
    vi.mock("./lib.cjs", () => ({ name: "mock" }));
    import { name } from "./barrel.js";

Under `bun test --aot` as one program `name`, `ns.name`, Reflect.get and `(await import("./barrel.js")).name`
read `undefined`. Object.getOwnPropertyDescriptor and a spread of the same object were right.

findNamespaceExport() leaves a member to the namespace object where the module that declares the variable
may be mocked. The names of a CommonJS file are variables of its ES face, and the mark sits on the file,
so the read was bound to a variable that nothing fills while the mock stands. Both are asked now.

* AOT: a function of a built-in module replaced by a writer the build can't see

    import found from "node:module";
    JSON.parse("0", () => Reflect.set)(found, "SourceMap", mine);
    function use() { return found.SourceMap(); }
    use();      // plain: mine's result; compiled: SIGSEGV

With `buffer.atob`, `Buffer`, `Blob` and all of `node:util/types` the write went through, a read saw it,
and the call by the module's name silently reached the original. main has this bug.

Flow analysis reasoned that start-up locks every member of a built-in that no statement writes. Nobody
locks the object of a module, and nobody should: stubs and instrumentation replace such members. A
holder that is a module's object, has no lock under the name and has escaped to code nobody sees now also
answers what was stored through the unknown object, so the call is tested and not bound.

* AOT: a variable read stale behind a method picked by a name known only at run time

    const handlers = {
      open(done)  { return { run() { done({ ok: true  }); } }; },
      close(done) { return { run() { done({ ok: false }); } }; },
    };
    const type = JSON.parse('{"type":"open"}').type;
    let result = null;
    handlers[type](r => { result = r; }).run();
    console.log(JSON.stringify(result));      // null, should be {"ok":true}

Silent, at default flags. Neither the verifier nor --aot-validate sees it; --aot-check=MovedLoads does.
main has this bug.

In cold code Select fuses a property read and a call into CallMethod. That operation's effects are
"unknown code", without its known callees. "Unknown code" is what functions entered by unknown code
do, and a function whose callers flow analysis all knows isn't among those. So B3 was told that the
call doesn't write the variable's word, and forwarded the earlier store to the load.

The read and the call are now fused only where the call's effects lie within those of unknown code.
New: --aot-sabotage=FusedCallsEnterOnlyUnknownCode.

* AOT: a setter laid by Object.defineProperty that stores through `this`

    import "node:util";
    class C { z = 0; }
    function run(given) {
      const o = given ?? new C();
      Object.defineProperty(o, "p", { set(v) { this.z = v; } });
      o.p = 1;
      return o.z;
    }
    console.log(run(), run([]));      // 0 1, should be 1 1

Silent. Where a TypeScript class declares `z?: number` the executable aborted. Twenty built-in modules
arm it by being imported anywhere in the program. main has this bug.

The library's text holds a function that lets accessors escape, so the setter escapes, rightly. For a
store with several receivers the setters found are then {unknown}, which covers the known setter, and the
branch that hands each receiver to the setters on its own chain asked the covered view and was skipped.
The instance was neither handed to the setter nor made to escape, so its field counted as stored once.

For a store, where unknown stands among the setters found, the receivers that haven't escaped are now told
apart, and each is handed to the setters laid on its own chain. A getter that writes through `this` and is
run by a spread had the same hole in the rule for copies. What flow analysis hands the optimizer is
unchanged on express, fastify and the typescript package.

* AOT: the test of a branch that passes on a proof stays in the branch's block

    function f(x, n) {
      let fuel = 3, b = x, c = 1n, e = x, a = x;
      const gt = { get v() { a = b; return 1; } };
      for (let i = 0; i < n; i++) c = e;
      while (c === b && fuel-- > 0) { gt.v; }
      b++;
      return e + 1;
    }
    f(1, 2); f("a", 2);

"Stopped while compiling f in SimplifyControlFlow", and the step that the message advises to switch off
isn't the one at fault. main has this bug; a neighbour with a value out of Map.get built on main and
aborted on this branch.

HoistLoopInvariantReads lifted the loop's test out of the block of its Branch, which passes a proof on
its taken edge. PlaceTypeTests then copied a part of the loop, and the SSA repair turned the Branch's
condition into a block parameter, which proves nothing. Of 58 varied forms 23 didn't build and none
built and answered wrongly. Such a test is no longer hoisted. Those loops now make an unchanging test in
every iteration: 1,031 functions of the public corpus change, 3,361 bytes fewer.

* AOT: a class is no longer recognized by its prototype's own `constructor` property

    const Base = t => class { constructor() { this.a = t; } };
    const Heir = S => class extends S { constructor() { super(); this.b = 5; } };
    for (let i = 0; i < 2; i++) {
      const D = Heir(Base(i));
      delete D.prototype.constructor;
      console.log(i, JSON.stringify(new D()));      // the second iteration: SIGSEGV
    }

With class fields it is silent: `{"a":1}` for `{"a":1,"b":5}`. Besides `delete`: Reflect.deleteProperty, an
accessor, Object.defineProperties, and a mixin helper that copies another prototype's own properties. Of
3,432 generated forms 472 were wrong, 164 by SIGSEGV. main has this bug.

From a class's second evaluation on, where no member guard is left, its class object and prototype object
are left out of the table of holders. Asked later whose prototype an object is,
ClassTable::classOfHolderLeftOut() read the object's own `constructor`. With that gone the answer was
"nobody's", and the base's constructor kept the object it had allocated in the base's shape.

A prototype object that is left out now names its class object under a private name of the class table:
read-only, not enumerable, not deletable, and seen by nothing that a program can ask.

* AOT: include what AOTCallRules.cpp uses

matchMethodCall() now asks context.build().isSabotaged(..), and BuildContext was an incomplete type there. Bun's build
precompiles a prefix header that brings AOTBuildContext.h in; WebKit's own CMake build does not.
…, build time (oven-sh#974)

* AOT: frames of a constant text given to eval or `new Function` ignored its `//# sourceURL=`

A constant text given to an indirect eval or to `new Function` is compiled ahead of time. Its frames were shown
under the URL of the file that evaluates it, whatever directive the text holds:
`at named (file:///$bunfs/root/main.js:1:36)` for `at named (webpack://app/a.ts:1:36)`.

The engine's half. The build reads the directive by the lexer's own rule; the test comes with Bun's half.

* AOT: a test file stuck on the top-level await of a compiled module was told nothing

Seven files that each await forever: plain `bun test` prints five `note: unsettled top-level await in ..` and
"and 2 more". A compiled run printed no note.

Bun walks JSC's module registry to find them. The engine keeps the records of an asynchronous graph's compiled
modules outside that registry. `AOT::forEachFileAwaitingAtTopLevel()` walks them by the same conditions.

* AOT: with a __mocks__ folder, a require() as the first load of a mocked file got the real file

    jest.mock("./src/old.cjs");                      // src/__mocks__/old.cjs lies beside it
    import.meta.require("./src/old.cjs").who;        // "real old" for "manual old"

No error in a run compiled as one program. Over layers, and for a written `require()`, the result was undefined
and then a TypeError. An `import()` right after it was right.

* AOT: the original of a file that had run before a mock was laid over it

Whoever asks for the original of a file of the program that has already run now gets what the file exported
before the mock: `module.exports` of a CommonJS file, a new object with the names of an ES module.
So too while the factory runs and nothing is laid yet. For a file that never ran the answer is empty.

* AOT: `globalThis[holder].__defineGetter__(key, f)` was refused on console, Intl, JSON, Temporal and WebAssembly

With `holder` and `key` out of data, the write was refused as a write to a read-only built-in. A read of a holder
under a key nobody knows notes the member objects it may give, and it noted the host's members alone: `console`
and `Intl` are the engine's entries.

The engine's members are noted only where their holder is the receiver of the read (`globalThis[k]`), not where
the read climbs to it. Every `object[key]` climbs to Object.prototype, and noting there made `Object` and its
methods answers of every such read, so `new contexts[i & 1].Request(..)` no longer knew its callee.

* AOT: vi.spyOn() through a barrel over a mocked module stored the spy where nobody reads it

    // dep.js is mocked by vi.mock("./dep.js", () => exports); star.js: export * from "./dep.js"
    vi.spyOn(star, "fn").mockReturnValue("spied");

Plain: `exports.fn === spy`, and dep's and star's `fn()` say "spied". Compiled: false, "fn", "fn". The spy was
stored into dep.js's own variable, which nobody reads while the mock stands.

Outside aot/: runtime/AbstractModuleRecord.cpp, two hunks inside `#if ENABLE(AOT)`, each acting only where
`dynamicDowncast<AOT::ModuleRecord>` answers. What a compiled module's record resolves while a mock stands is
not cached.

* AOT: after a test file resets the modules, the next one finds what ran before the first test file

A test runner hands each test file what ran before the first of them. Where a test file resets the modules, the
next one now finds the instances of that time again, as under plain `bun test`.

Three calls for the host: when the last preload has run, for each file that a reset takes out, and between two
test files, which names each file that is back.

* AOT: the body of a linked module did not run when a helper mocked it

    // linked.test.ts
    import { price } from "./mocks-tax";     // mocks-tax.ts: vi.mock("./tax", factory)
    import * as tax from "./tax";

Under `bun test` the graph is loaded before any module of it begins, so tax.ts is linked when the helper mocks
it. Plain runs its body there and then, once, and lays the mock over it. Compiled code now does the same.

* AOT: SIGABRT "exception check validation failed" where preload modules were evicted over two layers

Giving back the preloads held a throw scope of its own. A throw scope that ends asks whoever comes next for a
check, and after an early return that was the caller's own scope. It is a top exception scope now, asked after
each of the two calls, and `AOT::bringBackKeptFiles()` asks once more after its walk over the instances.

* AOT: a function with 14,000 live small objects was refused for its stack frame

    function big() { let v0 = c ? { a: 0 } : { a: seed }; /* .. 14,000 of them, all alive .. */ }

`error: TS100057: 'big' (f1) needs a stack frame of 1120000 bytes, over the limit: MaxFrameSizeInBytes`. Stock Bun
runs it. The limit stays. What filled the frame was objects allocated in it: a cell's stack slot is shared with
nothing, so the cells take the sum of their sizes. The planner now stops putting cells into a frame at the room
the frame has.

* AOT: in the second test file that mocks a module, vi.spyOn() reached the first file's mock

a.test.js and b.test.js each `vi.mock("./dep.js", () => exports)`. In b, in a run compiled as one program,
`vi.spyOn(ns, "fn")` on dep's own namespace object or through a star left `exports.fn === spy` false, made the
first file's `exports.fn === spy` true, and `fn()` was not spied. Plain and a layered run were right.

A record made for a search alone holds no status, so the end of a mock never let it go.

* AOT: no pass writes outside a function's tables of values and blocks in a release build

`Function::at()` and `edit()` index those tables through a span's data. The bound was asked under assertions
only, so in a release build a pass that held a stale number wrote outside the allocation and went on. The
compiler now stops on such a write. Reads stay with assertions.

* AOT: what the test runner hands out is held by native code

A module object reached through `module.require`, `import.meta.require` or `createRequire()()` in a test run is
handed out by the runner, not by code the build sees. Flow analysis now takes such a module's namespace and
object as held by native code. One field of the program's records says which modules those are.

* AOT: four walks over "what the loader holds" went through a mocked module to a file it hides

lib.mjs imports hidden.mjs; `mock.module("./lib.mjs", () => ({ v }))`; `await import("./main.mjs")`, which imports
lib. A file that only a mocked module imports is not loaded, yet:

- `Bun.plugin({ setup(b) { b.onLoad({ filter: /hidden\.mjs$/ }, ..) } }); (await import("./hidden.mjs")).e` gave the
  file's value for the plugin's, and `require.cache` listed hidden.mjs.
- Three more forms on the same walks.

No error. `bun test --aot` alone. main has these too.

* AOT: JSON.stringify with a list of names did not count as reading those names

    class B { constructor(x) { this.x = x; } get size() { return this.x + 1; } }
    console.log(JSON.stringify([new B(1)], ["x", "size"]));

threw "TypeError: 'size' was left out of the executable" for `[{"x":1,"size":2}]`. Without an error: a getter that
stores was not seen to store, and `C.prototype.q = { toJSON() { return "tj"; } }` gave `[{"q":{}}]` for
`[{"q":"tj"}]`. One row of the table of built-ins.

* AOT: the verifier stopped a build on a union member whose tag no member can hold any more

`type A = { tag: "a" }; type B = { tag: "b" }`, a member made in the module body whose tag only typing knows to be
"z", and `if (x.tag === "b") { kept = x; }`: "verification failed after NarrowConstantVariables .. TypeOutOfDate".

* AOT: lists made by one literal of constants were one cell though structuredClone() tells them apart

    const initial = { rows: [0, 1, 2].map(() => ["", "", ""]) };
    let state = structuredClone(initial);
    state.rows[0][0] = "x";

gave [x][x][x] for [x][][]. No error, default flags. main has this bug too.

All lists that one literal of constants makes become one cell where flow analysis says that they never change
and are never told apart. A built-in counted as telling apart only an operand that is itself a list. What an
operand reaches now counts too.

* AOT: an import that went on behind mock factories lost its referrer's order

`Modules::startImport()` parked an import behind factories with the module and the caller's kind alone, and
resumed it without the referrer's asynchronous order and with the default text of the import. Every other path
in the file carries both. Found in review. The hang it could have caused was not reproduced.

* AOT: `using h = monitorEventLoopDelay()` failed: "[Symbol.dispose] was not compiled into this executable"

    import { monitorEventLoopDelay } from "node:perf_hooks";
    { using h = monitorEventLoopDelay(); h.enable(); }

Eight of twelve ways failed: `using`, `await using`, `const d = h[Symbol.dispose]; d.call(h)`, a pattern,
`Reflect.get` on the object and on its prototype, `.bind(h)()`.

A function of the host that a lookup finds through an object nobody knows is marked as taken off its holder.
The mark is for functions written in JavaScript alone: marking every one kept six more features under `--trim`
in an elysia server.

* AOT: `f.apply(x, arguments)`, inlined, with an unknown callee: the list guards the reads of its own elements

The list that `apply` makes guards the reads of its own elements by its birth, so the verifier no longer stops
such a build.

* AOT: a call that Select loses stops the build

In the table of what each pass answers for, Select answered for every operation that goes away and might take
every handler away. It now answers for 11 opcodes, each read in the pass, and may take the handler from a loop
hint alone.

* AOT: one IR test's hand-written Check made its generic version ill-typed

definition-of-a-field-that-takes-any-value-in-a-proven-layout.ir: `Check v3 expectedType=L0` becomes
`RequireObject v3`. What the test is about, the definition of the field, is as it was.

* AOT: a release hint kept a list out of the frame

`found().map(part => part.size + i).length`: the list that `found()` makes lay in the frame and cost no cell, until
a hint that names it was taken for an escape: one cell of 48 bytes more a turn. A hint never counts against the
frame now.

* AOT: a copy of a list is read, written through a second name, and read again

The second read gave a wrong value. An executable, default flags, no error. main has this bug too.

* AOT: the mock of one test file reached the next

    // x.test.mjs: import * as u from "./user.mjs"; mock.module("./lib.cjs", () => ({ v: "mock v" }));
    //             user.mjs takes lib.cjs by createRequire()(..)
    // z.test.mjs, which mocks nothing:
    import * as ns from "./lib.cjs"; ns.v;           // "mock v" for "real v"

So too for `(await import("./lib.cjs")).v`. `import whole, { v } from "./lib.cjs"` failed with "SyntaxError: Missing
'default' export in module".

* AOT: `--explain=statistics` counts the method calls that are not fused

MethodCallsNotFused is the number of places in a program that held the shape of the stale-variable bug fixed in
oven-sh/WebKit#972. It is 0 in eight servers (express, fastify, hono, koa, elysia, Bun.serve, node:http, a thin
one).

* AOT: two IR tests of the counter need Bun's table and move to Bun's tree

* AOT: a name the build left out of a compiled module is named in the error

Code that the loader reads from disk (the original of a mock, a file taken out of `require.cache`) links to
compiled modules by their tables, and the build trims a table to what something names. An import of a trimmed
name failed with "export 'x' not found". It now says that the name was left out of the executable.

Outside aot/: runtime/CyclicModuleRecord.cpp, two hunks inside `#if ENABLE(AOT)` on the "export not found" path.
Both ask `globalObject->aotInstance()` first, so a run without compiled code enters neither.

* AOT: the compiler failed or aborted on a loop whose counter has two bounds

    function f(list, o) {
      const n = o.n; let i = 1;
      while (i + 1 < n) { if (i > list.length) break; i += 1; }
      return [i];
    }

called with n 2147483656 and with 3: "internal compiler error (ChooseRepresentations): UnsupportedConversion". With
`t += list[i]` in the loop the compiler aborted. Of 96 such plain loops 52 did not build, 8 by an abort. main has
this bug too.

Where `i + 1` is tested ahead of the step, the turn handed on what that test let through in place of the step.
But the step stood behind a second test of the counter.

* AOT: a quadratic step in Air's releaseDeadValues

To say what each place holds where paths meet, the joins of a block were filled from each later predecessor by
going again through every name that changed. They are now filled by the shorter of two ways.

Outside aot/: b3/air/AirReleaseDeadValues.cpp, +4, inside `#if ENABLE(AOT)`.

* AOT: four planted faults and a statistic for three passes that decide things at the top of a file

NarrowConstantVariables, DeferDefinitions and DeferClosuresInFields had no planted fault, and one had no counter.
No behavior changes without `--aot-sabotage`.

* AOT: the verifier stopped a build on a type test hoisted in front of a loop

"UnspecifiedValueInspected (TypeTest)" after ConvertCountersToIntegers. A default build gave the right answer
before and after this change.

The pass takes a type test that the head of a loop asks of its parameter in every turn and asks it once, of the
first value, in front of the loop. Where an object is carried out of a counted loop in parts into a second loop,
the head looks at the word through an assumption, and the new test did not. It asks through what the head asks.

* AOT: any mock of a file cost a closed program a tenth of its likeness to the executable

`mock.module("../knob.ts", () => ({ knob: 2 }))` of an unrelated one-line file: 89.7% of hono's functions compiled as
in the executable, for 99.1%. The original beside a mock is the file once more, from disk, as code the build has
not compiled, and every mock of a file raised that possibility. It is now raised only where something may ask
for the original.

* AOT: `spyOn(Response.prototype, "status", "get")` was refused though written out in full

"TypeError: Cannot spy on Response.prototype.status because built-in objects are read-only in compiled code". So
for every getter of Response.prototype, Request.prototype and Blob.prototype, and `Headers.prototype.count`: 17 of
42 accessors and methods asked.

* AOT: a built-in that has escaped and climbs the prototype chain lets out what stands above

An executable at default flags gave another answer than plain Bun. The thirteen stored programs,
classes-reached-through-instances/hidden-*, come with Bun's half.

* AOT: build time: what a spread copies is read once for a set of sources

`const all = [{ id: 0, k: 0 }, ..]` and n functions `function f7(i) { return { ...all[i], x: 7 }; }`: the step that works
out in which orders a literal's keys may come walked, for each spread, each object of the set of sources, and for
an object of an array written as data the whole data literal: n spreads x n objects x n nodes. No generated code
changes.

* AOT: build time: three quadratic steps in SSA repair and the greedy register allocator

A use that names a definition which dominates it is reached by that definition alone, so no join gets a
parameter for it. What reaches a join on each of its edges is found when the join is first seen to reach a use
and kept for the variables that have the same joins. No generated code changes.

Shared with the JIT: b3/air/AirAllocateRegistersByGreedy.cpp.

* AOT: build time: the owner of a block's parameter and the cycle of a block are looked up, not searched for

Two steps quadratic in the size of one function. Flow analysis looked through all blocks of the function for the
owner of a block's parameter, and through all again for the edges into that block, for the callee and the
receiver of every call. Both tables are now made once for a function.

* AOT: `--aot-validate`: a claim inside the value's own type asks nothing

Of the 367 B3 values and 112 blocks of a line `t(add, V[1], V[2])` in a validating build, 205 values and 77 blocks
belonged to three validations that asked what had just been asked. Default builds do not change.

* AOT: build time: the layouts of the receivers of a key are found once

For each key that is read and each set of receivers listed for it, flow analysis walked the set's members and the
lists of layouts that the members select. `{ ...defaults, ...parse(text) }` in a large program made that
quadratic.

* AOT: the warning for `require` inside node:vm is back, narrowed

A loader that leaves the program with no witness gives the warning only if some record of the program admits
code that the build has not seen.

* AOT: build time: the tables of a loop live as long as the pass

SeparateUnlikelyLoopPaths made, filled and destroyed, for every loop, tables with one entry for each value of the
whole function: loops x values.

* AOT: two planted faults for Map and Set lookups

`--aot-sabotage=GetsBehindHasOutlastWrites` and `--aot-sabotage=ObjectsWithTheTagOfAnotherAreAbsent`. No behavior
changes without them.

* AOT: build time: phi placement skips up the dominator tree

`let v0 = 0; .. for (3 turns) { v0 = v0 + a[1]; .. }` with n variables: three loop passes each demote 2 to 3 n values,
and the SSA fix-up after each asks of every variable where it is live. 90% of that was one inner loop.

Shared with the JIT: b3/B3FixSSA.cpp, b3/B3CompilationReport.h, and a new b3/testb3_bun_thread_jumps.cpp. Generated code is
identical.

* AOT: build time: what is copied onto a literal is asked by the set

`function f7(o, d) { return d <= 0 ? o : f8({ b: d, ...o, a: 7 }, d - 1); }`, n such functions in a ring: n turns for each
of n layouts.

* AOT: build time: three quadratic steps of PlaceTypeTests and SimplifyControlFlow in one function

"One literal of many names, each read by name". The uses of an object stand in the order of the function; a
binary tree over them holds a bit for each type that a use below a node names. The same bytes and answers on
every program asked.

* AOT: the phase log says what an image's tables are made of

After "AOT size of the image:" it prints "AOT size of the tables:" (17 sections) and "AOT size of the program
tables:". These numbers reached only `--aot-report`, which `bun test` refuses.

* AOT: two planted faults with their counters

For the store of a variable that waits for the end of a loop unless something else in the loop sees the place,
and for one rule more. No behavior changes without `--aot-sabotage`.

* AOT: idiomatic names in the B3 files that the JIT shares

Names and comments alone, in 36 files. No old name is left under Source.

Shared with the JIT: b3/B3LikelyPaths, B3Policy, B3PromoteLoopMemory, B3ReduceStrength, B3LoopInvariance and others,
and their testb3 files. Generated code is identical.

* AOT: `--aot-validate`: what was there before an object was made is not that object

`try { for (const a of JSON.parse(..)) run(a) } ..` where `run()` makes a class and `new I()`: the new object counted
as escaped and might be the list whose storage was tested ahead of the loop, so a verifying build stopped with
GuardNotAvailable. Default builds do not change.

* AOT: build time: a comparison walks what its arm dominates and asks the graph once

EliminateGuards went from 6 M to 774 M instructions between 9,600 and 19,200 statements of one function: past a
limit on tested types lay a quadratic walk.

* AOT: the objects that native code makes by itself go into both dumps of the table of built-ins

28 host objects and functions, as `hostObjects`: cell, function, prototype, fields.

* AOT: a verifying build goes on after a verification fails

The first failure of each function is kept and that function is verified no more. Where the pipeline ends the
build fails, no code is generated, and the errors begin with one line that counts them. Default builds do not
change.

* AOT: "TypeOutOfDate" says which way

The message now ends with whether the type that stands there is narrower or wider than what the rule gives.

* AOT: an import awaited at once begins behind its call

Precision of flow analysis alone. IR tests come with it.

* AOT: an import awaited through a cast

An `import()` awaited through a type cast is taken as one that is awaited at once. With `jest.mock`, 89.0% of hono's functions
compile as in the executable, for 71.7%.

* AOT: build time: the new objects behind a store are found by one walk

`let o = {..}; if (c0) o = {..}; else o.b += 0; if (c1) o = {..}; else o.b += 1; ..`: for each store the scanner walked
back through every join parameter behind its receiver and asked a list whether a parameter had been seen: cubic
in the branches of a function.

* AOT: `valueflow-solve every-order` also applies flow's results under every order

Test code. It compared the records of unseen code and the removable features; it now also applies the results to
the program, read anew, under 128 orders.

* AOT: two `Object.create(target)` sites made reads of the target's getters 20 times dearer

    const target = { get one() { return this.b + 1; }, two() { .. } };
    const a = Object.create(target), c = Object.create(target); a.b = 1; c.b = 2;
    (i & 1 ? c : a).one;       // 105 instructions a read; 5 to 15 with one call site

Every `Object.create` call site got a layout of its own.

* AOT: build time: tmps passed on the stack through a loop are priced block by block

With 8,000 typed sums in one function, the greedy allocator asked 16,384 times about one and the same Tmp, each
time from cost 0, walked all blocks to make its list and only then began to add up costs. The limit was passed at
block 161 of 8,900 on average.

Shared with the JIT: b3/air/AirAllocateRegistersByGreedy.cpp, b3/B3CompilationReport.h, b3/air/testair_bun_allocation.h.

* AOT: build time: an assumption is found by its value

`for (let k = 0; k < a.length; k++) a[k] = { v: k + 1 };` n times in one function cost n x n x n in flow's look at writes
of arrays. No generated code changes.

* AOT: the check of moved loads prints and goes on

A debugging flag. No code at default flags, none under the check alone.

Shared with the JIT: b3/B3Policy.h, one bool, false. b3/B3MovedLoadCheck.cpp is reached only where the compiler's
policy logs moved loads.

* AOT: the bounds put on tallies get a planted fault and a counter

`--explain=statistics` says TalliesBounded; `--aot-sabotage=TalliesOutrunTheirCounters`. No behavior changes without
it.

* AOT: a fused method call declares what its call did

The effects of a fused method call are unknown code united with what the call's known callees do. No size of
program decides any more whether a call is fused. This replaces the narrower fix for the stale variable in
oven-sh/WebKit#972.

* AOT: a planted fault for literals of constants

`--aot-sabotage` word alone. The stored programs come with Bun's half.

* AOT: a mock that lacks a name which a file of the project hands on

`vi.doMock("pkg", () => ({ v: "mock v" }))`, pkg a package in node_modules; user.mjs hands on a name that the factory
left out: `export { v, w } from "pkg"`. A mock of a module of another image is known there alone.

* AOT: accessors copied onto a built-in prototype were left out of the executable

    Object.defineProperties(Array.prototype, Object.getOwnPropertyDescriptors({ get extra() { return 41; } }));
    Reflect.get(new Proxy([1, 2], {}), "extra");

threw "'extra' was left out of the executable" for 41. Setters too, stored to by `Reflect.set` through a Proxy.

* AOT: a store to `module.children` did not drop the children that were waiting

    require("./lib/child.cjs"); module.children = [5]; module.children.length;     // 2 for 1
    module.children = 5; module.children;       // TypeError: children.indexOf is not a function

Under `bun run` each `require()` lists its child at once and the setter clears the list. A compiled module's
children wait in the engine until `children` is read. The setter now drops them.

* AOT: the compiler aborted on a copy of a list that is kept under a second name and written in the loop that reads it

    function tidy(list) {
      const copy = [...list];
      const result = { values: copy, changed: 0 };
      for (let i = 0; i < copy.length; i++) {
        if (copy[i] < 0) { result.values[i] = Math.abs(copy[i]); result.changed++; }
      }
      return result;
    }

`bun build --compile --aot` ended with "abort() called". main has this bug too.

* AOT: Reflect.construct() with an heir as its target gave the object the heir's field, and could segfault

    function Meter(size) { this.size = size; this.n = 0; }
    function Sub(size) { Meter.call(this, size); this.extra = "x"; }
    Sub.prototype = Object.create(Meter.prototype);
    new Sub(2);
    const o = Reflect.construct(Meter, [9], Sub);

`o.extra` was "x" for undefined and `"extra" in o` was true: the heir's field, which was never stored. A larger
program of the same shape, which is what Babel's helpers write for a transpiled class, segfaulted. An executable,
default flags. Bun's main, which pins an older engine, is right here.

An object of `new.target`'s class was allocated and the parent's body run on it, on the assumption that nothing is
claimed of how the objects of such a layout are built. That does not hold where the heir's fields are said to be
filled. No heir's class is selected there now.

* AOT: an input of the verifier that nobody read is gone

`VerifierInputs::otherFunctionsMayChange`: its declaration and the one line that set it. It belonged to effect
summaries computed on demand; the summaries that are handed over ready took their place and its reader went.

* AOT: under a standing mock, a file that was linked before the mock read the mock's values

    import { who } from "./m.js";
    test("..", async () => {
      vi.doMock("./m.js", () => ({ who: "mock" }));
      who;                                      // plain: still the real one
      (await import("./late.js")).read();       // plain: the mock
    });

Under plain `bun test`, `who` stays real for the file that was linked before the mock, late.js, which is linked
after it, reads the mock, and the factory runs at the first load that comes to it. Compiled, the factory ran at
the call and its values were laid over m.js's variables, so everybody read the mock. So too for what a preload
had loaded under a test file's `vi.mock()`, and for a package.

* AOT: build time: the parameter of a wide join waits for its sources

Type propagation joined the parameter of a block with many incoming edges again each time one of its sources was
typed: 24.0 of 30.7 G instructions at 8,000 states. A parameter of a block with 16 incoming edges or more that is
taken again now goes back into the worklist below the queued values that lie in front of the last of its sources,
and is joined once when they have been taken.

* AOT: deleting the oldest entry of a Map or Set stepped over every entry deleted before it

    map.delete(map.keys().next().value);      // how a hand-written cache lets its oldest entry go
    const [k] = set; set.delete(k);           // a queue

Each walk began at entry 0 and stepped over every entry that had gone before, so a turn cost the size of the
collection between two tables. The Map or Set object now holds how many entries at the front of its table are
known to be deleted.

Outside aot/: runtime/JSOrderedHashTable.h, +7, inside `#if ENABLE(AOT)`: a `uint32_t` member in what the object's size
class leaves unused, and its offset.

* AOT: build time: a store asks the lengths read above it, the nearest first

For every store into a list, flow analysis asked about every read of `.length` of that list in the function, at
about 9,000 instructions for a question that fails: stores x reads. A length bounds the position only where its
read dominates the access. A store now goes up the dominator tree from block to block that reads a length and
stops at the first proof. No generated code changes.

* AOT: where a generic copy of a loop comes back, a test that narrows gets no other definition

Where the generic copy of a loop comes back to the typed code, it tests again the values that the pass narrows and
hands each proven value over as another definition of that value. A comparison that stands ahead of the loop and
uses what an earlier test has proven was such a value; SSA repair merged the two into a block parameter.

* AOT: the row of a run-time function holds what its operation declares

B3 is told the intersection of an operation's effects and the declared effects of the C++ function or stub that it
calls. A heap that the function's row leaves out is lost however right the operation's row is, and nothing tied
the two tables together.

The schema's generator now checks, in every build, that what an operation with `runtime = F` is declared to write,
read or call lies within F's row, unless a table says why not; a line of that table that no longer applies is an
error too. The check found four mismatches, in the rows that two throwing operations call. Those rows are fixed.
No generated code changes.

* AOT: a test file's load is noted in the layers below

    // a.test.mjs
    import "./setup.mjs";       // vi.mock(path, async importOriginal => ..) of two packages and of a barrel
    import demo from "./demo.mjs";      // imports that barrel

In a test run compiled as several layers, which is the form a large run takes under `--parallel`, this printed
something else than plain `bun test` and a run compiled as one program do.

* AOT: two planted faults and a counter for two rules of flow analysis

`--aot-sabotage=BuiltinsLookAtTheirOperandsAlone` undoes the fix for lists of one literal of constants that
`structuredClone()` tells apart. One word and one counter more. No behavior changes without `--aot-sabotage`.

* AOT: a planted fault and two counters for lists that a loop leaves alone

HoistLoopInvariantReads reads a list's length once, and tells the tests of positions that length, where every list
that the loop writes is held apart from the measured one. It had no counter and no planted fault. No ordinary
build changes.

* AOT: a comment says why a wide join begins at 16 edges

One comment line in aot/ir/AOTTypePropagation.cpp.

* AOT: promoteLoopMemory resets the owners of values, and two checks of assertion builds ask the right thing

promoteLoopMemory reads `->owner` in three places and never reset the owners. The TypeScript compiler's bundle enters
the pass with null owners in 90 procedures, on values placed by insertion sets. No program is known to crash on
it. `m_proc.resetValueOwners()` now stands at the head of `run()`, with a test that the old pass dies on.

`SwitchValue::fallThrough(const BasicBlock* owner)` asserted `hasFallThrough()` without its argument. A check in
testb3_bun_vectorize_loops.cpp disassembled the whole allocation, which is rounded up, and so read the remains of an
earlier compilation; it now disassembles the bytes of the link buffer. No release build changes by these two.

Shared with the JIT: b3/B3PromoteLoopMemory.cpp +1, b3/B3SwitchValue.cpp +1 -1 (inside an ASSERT), and two testb3 files.

* AOT: three calls into the compiler's run time that a run without compiled code made ask first

Outside aot/: runtime/ObjectConstructor.cpp +1 -1, runtime/CallData.cpp +3 -1, runtime/CloneSerializerBase.h +2 -1. Each
stood inside `#if ENABLE(AOT)`, which is on in every Bun, so a plain run made the call; none of them changed an
answer there. Each now begins with `vm.hasCompiledCode()`.

* AOT: a verifying, layered test run stopped with "InvalidType: type 915 is not canonical"

A project whose file calls `spawnSync()` of node:child_process under @types/node, run over two or three layers with
the verifier on: "internal compiler error (ReadAndVerify): InvalidType: type 915 is not canonical, or its set of
layouts is empty or open", and none of the test files ran. A field of a record of a lower layer that takes no
object now has a type without objects.

* AOT: a counter for the walks over a Map or Set that begin behind the deleted entries

One statistic, counted where the code for the first step of such a walk is emitted. No generated code changes.

* AOT: `bun test --aot` over forked `export *` with a mocked module at the end was killed at 52 GB

Two modules a level, each `export *` of both of the next level; the last level stars m.mjs;
`mock.module("./m.mjs", () => ({ m: "mock m" }))`; main.mjs: `import { m } from "./l0a.mjs"`. 12 levels took 1 s. At
26 levels a run compiled as one program was killed at 118 s with 52.7 GB resident. Plain takes 0.1 s. Bun's main is
right here.

Walks guarded against rings by their path alone went down every way: two to the power of the levels. This is the
run's half; the build's half is in Bun.

* AOT: a read of a copy of a list expects the storage of the list it was copied from

    const xs = [1.5, 2.5, NaN, 4.5];
    const b = xs.with(2, 9);
    b[i & 3];       // in a loop

A list of numbers with NaN among them is known to hold values of any kind. Reads of its copy looked the storage up
each time. Speed alone.

* AOT: a store to an object that native code holds does not enter setters hidden behind unknown twice

test/aot/servers/a-test-run-compiles-what-an-executable-compiles-whatever-the-order-of-the-rules-of-flow-hono.test.ts in
Bun went red with oven-sh/WebKit#972: a test run and an executable compiled 98.3% of hono's functions alike, for a floor
of 99%. It is 99.4% now.

Where no code outside the image can run, the library's export holders are kept out of what has escaped and are
held by native code. The fix for a setter made with `Object.defineProperty` took "missing from escaped" for "nobody
covers this receiver" and entered eleven of the program's setters with a library prototype as `this`. One line.

* AOT: a module that a failed graph left linked runs its body ahead of a mock

all.ts: `import "./throws"; import "./tax"`. `await import("./all")` rejects with what throws.ts threw. Then
`vi.mock("./tax", () => ({ rate: 0.5 }))`: plain runs tax.ts first; compiled code never ran it. The next test file's
`import("./tax")` then read 0.5 for 0.2, without an error, and where tax.ts itself throws, plain's `vi.mock()` throws
that error and ours returned.

* AOT: `new WebAssembly.Suspending()` and `new WebAssembly.Tag()` without an operand gave another error

`new WebAssembly.Suspending()`: "Argument 0 must be a function" for "new WebAssembly.Suspending() requires 1 argument".
`new WebAssembly.Tag()`: "undefined is not an object" for "WebAssembly.Tag constructor expects the tag type as the
first argument." An operand that is not written was handed over as undefined. Two rows of the table of built-ins.

* AOT: a JSON.stringify in a run without compiled code no longer watches levels

Outside aot/: runtime/JSONObject.cpp +8 -4. `#if ENABLE(AOT)` is on in every Bun, so in a plain run a `JSON.stringify`
whose text passed 64 KB turned the compiler's watch on levels on, and from there every nested value took the
unlikely branch. No answer changed. `m_vm.hasCompiledCode()` now stands in front at both places.

* AOT: build time: what may change a list's length is looked for once

`{ const l = new Array(n); for (let k = 0; k < n; k++) l[k] = { v: k + 1 }; r.push(l); }` n times in one function: 400 such
statements cost 84 G instructions. Every list is made with the same number, so each loop's `k < n` may speak of any
of them, and they were tried in turn. No generated code changes.

* AOT: the run time stops a program that changes a compiled object in a way the compiler concluded never happens

With a plain message, in every build and not only in the checking ones. Compiled code is unchanged. One planted
fault comes with it.

* AOT: SSA repair no longer gathers the edges into a wide join

The edges into a join of 16 or more were grouped by their arguments, and the grouping compared the arguments before
they were renamed. No program is known to show a wrong answer by it. Found in review of this pull request. The
gathering is switched off.

* AOT: nine rows of the table of run-time functions say what their bodies write

The table now names every heap that these C++ bodies write, among them the field that a deferred closure is stored
into and the words that moving a field to the extra properties changes.

* AOT: "ASSERTION FAILED: m_moduleEnvironment" under `bun test --aot` in a build with assertions

An import that resolves to a compiled record has no module environment. The block that fills import slots for a
shared executable now leaves it out. It made runner-suites/mock-module-4, -5 and -6 red on Bun's ASAN lane.

Outside aot/: runtime/JSModuleRecord.cpp +6: an include, and five lines inside `#if ENABLE(AOT)` that begin with
`vm.hasCompiledCode()`.

* AOT: the list of planted faults in compile-call.def is laid out anew

The same words. Two groups of them change places and three get lines of their own. With the former layout the
generated compile_call_enums.rs had 1,001 lines, and the schema's generator refuses that file: "people read it, so
its emitter has to split it".

* AOT: no added comments in the files that are shared with the rest of JavaScriptCore

The comment lines that this pull request added under b3, b3/air and runtime go: 50 lines in 13 files. Two comments in
b3/B3Policy.h that it had reworded get their old words back. No line of code changes.

* B3: `continuesAfterMovedLoadReports` for `reportsOfMovedLoadsComeBack`

A rename, and nothing else: the member of ValidationPolicy at four places, and the local `reportComesBack` becomes
`continuesAfterReport` at six in B3MovedLoadCheck.cpp.

Shared with the JIT: b3/B3Policy.h +1 -1, b3/B3MovedLoadCheck.cpp +6 -6.

* AOT: `spyOn(Bun.CryptoHasher.prototype, "algorithm", "get")` failed in a test run compiled as two layers

"TypeError: Cannot spy on Bun.CryptoHasher.prototype.algorithm because built-in objects are read-only in compiled
code, and the build didn't see a test replace this one", with the spy written out in full. So too
`Bun.CryptoHasher.prototype.byteLength` and `Bun.SHA1.prototype.byteLength`. The spy's question went to one image, the
one that ran when `spyOn()` was called, and another had locked the holder. Every image of the realm is asked now.

* AOT: the compiler aborted in ExpandIteration under a lowered limit

`function f(l) { return [...l].length; }`, called with a list, a Set and a string, built with
`--aot-limit=MaxVersionedIterationBytes:1`: exit 134, "Stopped while compiling in ExpandIteration". The limit promises a
loop that is not optimized. Default builds do not reach it.

* testb3: two graphs take their arguments eagerly

An ArgumentValueList appends a new ArgumentReg to its block at every `arguments[i]`. Fetched late, it landed behind
the Check that uses it in one test and behind the block's Branch in the other. Both are faults of the tests' own
graphs, seen only where B3 validates. Upstream's own cases write `.eager()`.

Shared with the JIT: b3/testb3_bun_placement.cpp +1 -1, b3/testb3_bun_selection.cpp +1 -1.

* AOT: a hardened arm64 executable starts where a page has 64 KB

It aborted at start: exit 134. Found in review of oven-sh/WebKit#972. Generated code changes in hardened Linux arm64
builds alone; every other build gets a macro's new name and nothing else.

* AOT: the image that runs is called so

A local in AOTBuiltinCells.cpp is renamed from `first` to `running`: it is the image that runs, not the first of the
realm. No behavior changes.

* AOT: two imports that wait for one asynchronous mock factory

`mock.module("./lib.mjs", async () => (await later(), { v, kept }))`, then
`await Promise.all([import("./user.mjs"), import("./other.mjs")])`, where both import lib.mjs: "ReferenceError: Cannot
access 'v' before initialization". Plain gives both the mock. The first import that waited took the factory's promise
off the list, and the second found nothing pending.

* AOT: `vi.mock("node:fs")` without a factory failed with "Circular import" in a run compiled as several programs

So too `vi.mock("node:path", { spy: true })`, `jest.mock("node:os", () => ({ ...jest.requireActual("node:os"), .. }))`
and a `__mocks__/fs.js` that calls `jest.createMockFromModule("fs")`: 'error: Circular import: "node:fs" is imported by
a module that its own mock factory loads while it runs', and the file ran no test. Plain, and a run compiled as one
program, are right. The library's own request for one of its modules runs no waiting mock.

With it, one line of flow analysis: what `jest.requireActual()` hands out of a module that native code makes has
escaped. The front end's half in Bun needs it.

* AOT: each image's "is asking the host" is put back to its own

`JSModuleLoader::fetchSynchronously()` raised the flag for every image of the realm and restored all of them to the OR
of what they were, so one image in such a scope left the others stuck at true. With one image nothing changes. And
where the loader's registry has nothing, the other images of the realm are asked for a record that is not compiled.

Outside aot/: runtime/JSModuleLoader.cpp +7 -6, inside `if (vm.hasCompiledCode())`.

* AOT: "Unchecked JS exception" from `spyOn()` of an export behind two `export *`

JavaScriptCore's exception-scope validator aborted the run: `Modules::tryReplaceExport()` had no throw scope. It shows
only with the validator on, as on Bun's ASAN lane, where it made test/aot/three-layers-agree.test.ts and
three-layers-agree-2.test.ts red.

* AOT: six more calls into the compiler's run time that a run without compiled code made ask first

Outside aot/: runtime/JSMicrotask.cpp +3 -2, runtime/JSObject.cpp +2 -2, runtime/RegExpConstructor.cpp +2 -1,
runtime/RegExpGlobalData.cpp +2 -1. Each stood inside `#if ENABLE(AOT)`, which is on in every Bun. Each now asks
`vm.hasCompiledCode()` first. No answer of a plain run changes.

* AOT: in a test run a built-in object takes a name that it only inherits

`spyOn(Uint8Array.prototype, "set")`, `Uint8Array.from = f`, `Object.defineProperty(Map.prototype, "toString", d)` and a
getter for `length` on `Uint8Array.prototype` failed with a TypeError: "a test can't add this one".

* AOT: a mock of a JSON file never ran over layers

`vi.doMock("./data.json", () => ({ default: ["mocked"] }))` in a test file, and
`import data from "./data.json" with { type: "json" }` in what it imports: over layers the factory never ran and the
importer read the real data, without an error. A run compiled as one program was right.

* AOT: the enums of compile-call.def are generated as five Rust modules

compile_call_enums.rs had reached the 1,000 lines that the schema's generator allows a file that people read. It stays,
as five `pub use`. The same 3,125 generated items, the same schema hash, the same C++ outputs.

* AOT: three planted faults for what lies in a frame

Three words at the end of `enum Sabotage`, and the places in the frame-allocation passes and AOTEnvironments.cpp that
read them. No ordinary build changes.

* AOT: an executable's TypeError for a name that a built-in only inherits gave false advice

`holder[name] = f` with `Uint8Array.prototype` and "set": the message advised "Spell out the object and the name where it
does". No spelling opens that in an executable. An earlier commit of this pull request brought it.

* AOT: the mock of a built-in module outlived its test file

a.test.js: `vi.mock("node:fs", ..)`. b.test.js: no mock. src/uses.js, which both import, reads `existsSync` by the
default, the namespace and a name. In b.test.js plain gives false, false, false; compiled over layers it gave
"mocked" three times, without an error.

* AOT: behind `export *`, a mock that took the original had no names

barrel2.js: `export * from "./barrel.js"`.
`vi.mock("./barrel.js", async original => ({ ...(await original()), x: "over x" }))`.
user.js: `import * as ns from "./barrel2.js"`. Written reads were right; `Object.keys(ns)` was empty for plain's x and
y, `ns[key]` was undefined and `"x" in ns` false, without an error.

* AOT: build time: what runs each turn of a loop is looked for inside the loop

"Does every turn of the loop pass this block" was answered by a walk from the loop's header that nothing kept inside
the loop: it left by the exit and went through the rest of the function, for every append in a loop. No generated
code changes.

* AOT: `vi.spyOn(EventTarget, "prototype", "get")` ended the whole test run

`vi.spyOn(EventTarget, "prototype", "get").mockReturnValue("spied"); typeof EventTarget.prototype`: plain gives "string";
compiled, the run ended with "AOT: built-in cell 48 (key 4024, EventTarget.prototype) is not in this realm".
`vi.spyOn(WebSocket, "OPEN", "get")` read 1 for "spied", without an error. A spy on a member that compiled code takes for
a constant is now refused with a TypeError. Bun's half calls `JSC::AOT::isMemberTakenForConstant()`, declared here.

* AOT: one visitor names every member of ExpandIteration's arm state

The abort under a lowered limit was a member added to `struct ArmState` and forgotten in a hand-written list. One
structured binding behind the struct now names all eleven members, so a member added anywhere stops the build at that
line. No generated code changes.

* AOT: a mock laid over an ES module that has run adds no name to it

`await import("./dep.mjs"); mock.module("./dep.mjs", () => ({ own: "mock own", real: "mock real" }));
await import("./user.mjs")`, where user.mjs has `import { own, real } from "./dep.mjs"`: plain throws "SyntaxError: Export
named 'own' not found in module"; compiled code loaded user.mjs, which read undefined and "mock real". So too with
`jest.doMock()`, with `require()` of the importer, and through one `export *` or two.

* AOT: a name that a compiled module's table lacks is refused in plain's class and words

It was "TypeError: 'nope' was left out of the executable .. This is a bug in Bun." It is now a SyntaxError that begins
with plain's sentence: "Export named 'helper' not found in module '<path>'." No run is known to reach it without a
planted fault. Found in review of this pull request.

* AOT: five counts of the front end become rows of the table of limits

Five constants decided how far the front end looks into types, and nothing could lower them. They are rows of
limits.def now, with the values they had, and `--aot-limit` lowers them. Default builds do not change.

* AOT: a test that ends the mock of a built-in module itself

`vi.mock("node:fs", ..)` hoisted, and a test calls `vi.doUnmock("node:fs")`: plain goes on reading the mock through the
code under test until the test file ends. The fix for a mock that outlived its test file, earlier in this pull
request, handed the module over at once, so the rest of that file read the real one, without an error. It is handed
over where the test file ends.

* AOT: seven spies on a `prototype` are taken again

`vi.spyOn(FormData, "prototype", "get").mockReturnValue("spied"); typeof FormData.prototype` gives "string" in plain and
on Bun's main. The refusal of spies on members taken for constants, earlier in this pull request, refused it too, and
the `prototype` of Bun.Cookie, Bun.CookieMap, Bun.WebView, DOMException, PerformanceObserver and WebSocket.

* AOT: SSA repair gathers the equal edges into a wide join again, and compares them behind the renaming

The gathering was switched off earlier in this pull request because it compared arguments before they were renamed.
It now runs behind the renaming of uses and holds each edge's own arguments against the first edge's: an edge that
differs keeps its own and stays where it is. A release assertion counts the arguments of every edge. With a test in
IR. Generated code changes as the gathering first changed it.

* AOT: the verifier refuses a store that may create a field below an accessor

`PutSlotOrAdd`, or a key of `PutSlots` that may add, on a field that flow analysis marked as an accessor on the
prototypes is now an internal error. Those two operations declare no write of the member guards, and that is right only
while no such store exists. A rule of the verifier, a diagnostic and two tests in IR. No generated code changes.

* AOT: a body asks for the room of its array methods with its own

`function pricesOfEven(list) { return list.filter(f).map(g); }`, called from many places of one long function: the
helpers' bodies spent the caller's whole allowance for inlined copies, and then every `filter()` and `map()` inside them
found it spent. Each copy was two loops, two lists and a call for every element, where the helper by itself is one
loop. Speed alone.

* AOT: the image lists the modules that a test may mock and that are loaded under another name

"../a" and "../a.js" for a.ts, "../a" for a/index.ts. Three flags of a module in program-records.def, a table of the image
(`modulesReachedUnderOtherNames`), and `isReachedUnder()` for Bun to ask. An executable's table is empty.

* AOT: every image is asked before any is told of a copy from disk

Where a realm runs several images, each was asked in turn whether a copy of a file may run from disk, and each that
said yes set its flags at once: the flags were set before the overall answer was known. No program reaches the
difference. Found in review of this pull request.

* AOT: a loader that is out of sight hands out the objects of Bun's own modules

    import buffer from "node:buffer";
    const mine = () => "mine";
    JSON.parse("0", () => process.getBuiltinModule)("node:buffer").atob = mine;
    console.log(buffer.atob("YQ=="), buffer.atob === mine);   // "a false" for "mine true"

Hidden code fetches the module's object by the module's name, so the object had never escaped. Where a loader has
escaped, the objects of all public modules have too. Bun's main is right here. Bun's half goes with this line: it puts
back that `buffer.atob` and the global `atob` are one function, without which `Object.assign(buffer.atob, { kept: 7 });
atob.kept` was undefined.

* AOT: `require()` of a module whose import had been mocked failed once the mock had ended

`jest.doMock("./dep", ..); require("./user.mjs").seen(); vi.doUnmock("./dep"); require("./user.mjs").seen()`:
"ReferenceError: Cannot access 'a' before initialization"; plain gives the real values. The commonest form: the mock
ends with its test file and the next test file requires the user. The mock stood in place of a module whose body
never ran, and a compiled `require()` of an importer that had run did not pay what was owed.

* AOT: a door for Bun to say whether a program's texts are held, the engine's half

One trailing member of ModuleHost, `holdsTextsOfProgram`, and the condition in `startImport()` that asks it. It is null
in today's Bun, in the jsc shell and in testaot, and null means as before: by itself this changes nothing.

It is for the order in which two `import()`s settle in an executable:
`await Promise.all([import("./a.mjs"), import("./b.mjs")])`, where a.mjs and b.mjs import each other, fails with
"ReferenceError: Cannot access 'fromB' before initialization". Bun's main is right there. Bun's half cures it.

* AOT: behind the mock of a built-in module its importers read the module again

a.test.js: `mock.module("node:util", ..)` ahead of the load, then `import("./src/uses.js")`. b.test.js imports the same
file and has no mock. In b.test.js `all.format` and `format` were undefined ("TypeError: all.format is not a function")
and `Object.keys(all).length` was 2 for 47. The namespace object listed the mock's names in the next test file, without
an error, for 29 of 30 built-in modules tried.

* AOT: `$<name>` in a replacement text reads any name off the groups

    class G { get n() { return "named"; } }
    const re = { flags: "", exec(s) { .. r.groups = new G(); return r; } };
    RegExp.prototype[Symbol.replace].call(re, "a", "[$<n>]");    // [named]

An executable threw "TypeError: 'n' was left out of the executable". Where the getter stores `this.reads = 1`, it printed
`0[named]` for `1[named]`, without an error. A row of the table of built-ins, and the arm of flow analysis that serves it.

* AOT: "this assignment always throws" is a build error only if every run reaches the write

`if (Array.prototype.at) { ...; process.exit(0) } Array.prototype.at = polyfill` did not build: TS100014. The check asked
only whether the write's block dominates every return of a module body that is always evaluated. A call that may end
the process, or an explicit throw, ahead of the write now makes it the warning "throws if it runs", and the write is
refused at run time as before.

* AOT: the compiler's own check stopped the build where an object without a prototype is handed to a parameter declared as a list

The meet of what flow analysis knows with what a former entry check claimed has two sound types, and neither lies
inside the other; in one order the proofs were lost. What stores behind a former entry check hold is now said at the
stores. With a statistic. Three stored programs are in Bun.

* AOT: a mock in the middle of a chain of re-exports answers

leaf.js declares x. barrel.js: `export { x } from "./leaf.js"`. barrel2.js: `export { x } from "./barrel.js"`.
`vi.mock("./barrel.js", () => ({ x: "over x" }))`, the one in the middle. `import { x } from "./barrel2.js"`, or `ns.x` and
`ns[key]` off its namespace object: plain and Bun's main give "over x"; this branch gave "ReferenceError: Cannot access
'x' before initialization", and with a factory that takes the original, the real x without an error. This is the run
time's half, for computed reads and keys; the written reads are cured in Bun.

* AOT: the schema's generator no longer refuses a long file

The check on the lines and bytes of a generated file goes. Nothing but the check read its two limits. All 67 outputs
are the same bytes.

* AOT: a door for the original of a mocked package, the engine's half

One more trailing member of ModuleHost and the run time behind it, with native tests. By itself it changes nothing.

It is for node_modules/reads/index.js `const dep = require("dep"); exports.seen = () => dep.value();` and a test with
`import { seen } from "reads"; vi.mock("dep", () => ({ value: () => "mocked" }))`: plain gives "real", because a module
that Vitest externalizes gets the original of what `vi.mock()` mocked; compiled code gives "mocked", without an error.
Bun's half cures it.

* AOT: the answer of a loop's first question has one reader

A type test put on the edge that enters a loop sends what fails there past the header, to the arm where the header's
own question fails. All that the header defines was made again on that way, but not the header's type test itself: an
arm that returns the answer, or branches on it again, read a value that had not run. With a test in IR.

* AOT: five more calls into the compiler's run time that a run without compiled code made ask first

Outside aot/: bytecode/RepatchInlines.h, llint/LLIntSlowPaths.cpp, runtime/JSObjectInlines.h (two places),
interpreter/StackVisitor.cpp: +7 -5 in all, every line inside `#if ENABLE(AOT)`. Each now asks `hasCompiledCode()` first.
No answer of a plain run changes.

* AOT: values copied onto an object of the realm escape

    Object.defineProperties(Event.prototype, Object.getOwnPropertyDescriptors({ laid: { deep: function () { return 1; } } }));
    typeof new CustomEvent("x").laid.deep;      // "undefined" for "function", exit 0

With `const shared = { n: 0 }` laid so as `counter`, `new CustomEvent("x").counter.n = 7; shared.n` ended the executable:
exit 134, "StoreOfOtherType of field n .. which compiled code reads without a test".

* AOT: a test that a branch narrows by stays in its loop, wherever the branch stands

    function f(a, b, c) {
      if (c === a) { c ^= 1; }
      for (let i = 0; i < 1 && (c === a || b !== c); i++) { if (a === c) { console.log(a === c); } }
      return c;
    }

The compiler aborted at default flags: "Stopped while compiling f in PlaceTypeTests". Bun's main builds it. `c === a` in
the head of the loop and `a === c` in its body are one value with two branches, and the hoisting of loop-invariant reads
took it in front of the loop. With a test in IR.

* AOT: a `require()` answers the original until an asynchronous mock factory has settled

early.cjs: `module.exports = require('cjs-pkg')`. The test file imports early.cjs and says
`vi.mock('cjs-pkg', async importOriginal => ({ ...(await importOriginal()), hello: () => 'mocked' }))`. A `require()` cannot
wait for a factory: in plain it answers the original until the factory has settled. The run time's half; the rest is
in Bun.

* AOT: a receiver that leaves may be any object

A second rule of flow analysis behind "an escaped built-in that climbs lets out what stands above". No program is known
that answers otherwise than plain today. With a planted fault, a statistic and tests in IR.

* AOT: no copy of a hot loop's reads for a list that may hold undefined

    const q = rows.map(r => r.qty);                                // one row has no qty
    for (let i = 0; i < q.length; i++) total += q[i] ?? 1;
    for (let i = 0; i < q.length; i++) if (q[i] == null) count++;  // "5 0" for "5 1"

A wrong answer at default flags, without an error. The pass copies a hot loop's reads for storage that holds any value,
behind a failed test for storage of doubles. The copy left into the exit of the loop for doubles, into code where
`q[i] == null` had been answered "no" by the storage and its read was gone. This only takes cases away from the pass.
The tests in IR that say "there is a copy" are restated.

* AOT: "Stopped while compiling" says that an earlier step may be at fault

The step that is named may only be the first to read what another one left. The text now adds: "An earlier step may be
at fault: --aot-check=verify-each-pass names it."

* AOT: three more places look at the exception first

The end of an async generator's step asked `!promise || scope.exception()`, so the second half was never asked where
there was no promise. A namespace object asked to delete declared a scope with a check still pending. They show only
under JavaScriptCore's exception-scope validator, as on Bun's ASAN lane.

* AOT: what a mock replaced behind the stars of its file comes back when it ends

leaf.cjs: `exports.x = "real x"`. barrel.js: `export * from "./leaf.cjs"; export const own = "own"`. user.js reads x off
barrel.js. a.test.js: `mock.module("./barrel.js", () => ({ x: "mock x" }))`. In the next test file user.js still read
"mock x", without an error; plain reads "real x". So too with a CommonJS package for leaf.cjs.

* Revert "AOT: a JSON.stringify in a run without compiled code no longer watches levels"

With it, in a run without compiled code, `JSON.stringify` of an object that holds itself, with an indent, took about
0.65 s a call, as in Bun 1.4.3. Bun's main finds the cycle early: 300 calls in 0.1 s. Every answer was right.
runtime/JSONObject.cpp is again as it stood before that commit of this pull request, byte for byte.

* AOT: three more things ahead of a locked write make "this assignment always throws" a warning

The first of them: a call that is handed a built-in that may end the process as its receiver or an argument: `process.exit.call(..)`,
`.apply(..)`, `Reflect.apply(process.exit, ..)`, `[0].forEach(process.exit)`. Behind the commit
that made TS100014 an error only if every run reaches the write.

* AOT: a planted fault for the copy of a hot loop's reads

One word in compile-call.def and the one condition in AOTArrayCapacities.cpp that asks for it. No generated code
changes. Thirteen stored programs and the word's test are in Bun.

* AOT: getters that a bundler's `__export` lays on an object of the realm escape

    function __export(target, all) {
      for (var name in all) Object.defineProperty(target, name, { get: all[name], enumerable: true });
    }
    __export(Event.prototype, { laid: () => "mine" });
    new CustomEvent("x").laid;      // "'laid' was not compiled into this executable" for "mine"

Where that idiom is recognized the getters are found by name, on a way past the rule that lets what is laid on a
built-in escape. One line.

* AOT: switch off the clamp of loop bounds

On two random programs of testb3 its code parted from level 0. The tests that rest on it keep their expectations under
a TODO.

* AOT: the factory of a mock that imports the module it mocks, and fails, was called twice

`mock.module("./m.js", () => { calls++; imports.push(import("./m.js")); throw ..; })`, then user.js, which imports m.js, is
loaded. That import comes to the mock behind the end of the run, when the mock waits to be run again, so compiled code
called the factory a second time; `bun test` calls it once. In a build with assertions it stopped at
"module->status() == Status::Evaluated", as on Bun's ASAN lane.

Outside aot/: runtime/CyclicModuleRecord.cpp +7, inside `#if ENABLE(AOT)` behind `vm.hasCompiledCode()`;
runtime/AbstractModuleRecord.h +1: an inline `clearTopLevelCapability()`, which only that block calls.

* AOT: the way to a mock goes on through a table that lacks the name

barrel2.js has x by a star from barrel.js, which says `export { x } from "pkg"`, and "pkg" is mocked: "ReferenceError".
barrel.js's table has no entry for x, because a table lists what somebody reads off the object of its module. Bun's main
is right here. Behind "a mock in the middle of a chain of re-exports answers"; the front end's half is in Bun.

* AOT: a planted fault for what stores behind former entry checks hold

One word in compile-call.def, and the place in AOTEntryChecks.cpp that reads it. No ordinary build changes.

* AOT: a mock of a built-in module that a test ends itself goes on for whoever was linked

`bun test --aot` compiled as one program, at default flags, gave another answer than `bun test`, without an error. Under
aot/runtime alone; no generated code changes. Two tests are in Bun.

* AOT: the run time reads no overloads

234,241 bytes of read-only tables that only the compiler read had come to be kept in executables: an earlier commit of
this pull request asked the table of overloads a question at run time. The run time no longer reads them.

* AOT: the accessors of a library module that the test runner hands out are entered

`const util = jest.requireActual("node:util"); Object.assign(util, { ...util })`, or
`for (const key of Object.keys(util)) util[key] = ..`: "'formatWithOptions' was not compiled into this executable because
nothing that the compiler can follow calls it". Plain gives no error. The member is an accessor of the module's export
object, and its setter is called only by a store under a key that the build can't read.

* AOT: a helper that mocks a package which the test file comes to through other files

demo.test.ts: `import "./helper.ts"; import demo from "./demo.ts"`. helper.ts:
`vi.mock("confirm", async importOriginal => ({ ...(await importOriginal()), default: wrapped }))`. demo.ts imports
prompts.ts, which says `export { default as confirm } from "confirm"`. Over layers: "ReferenceError: Cannot access
'default' before initialization". Plain, and a run compiled as one program, are right. Bun's main has it too.

* AOT: every image is told of a file that a plugin's `onLoad()` filter names

Such a file was left to the host in its own image and the other images were not told, so in the image above its
importer was served compiled where a run of one image leaves it to the loader.

* AOT: what a copy writes onto an object of the realm escapes

    Object.assign(Event.prototype, { get laid() { return { deep: function () { return 1; } }; } });
    typeof new CustomEvent("x").laid.deep;      // "undefined" for "function", exit 0

With `get laid() { return shared; }`, `new CustomEvent("x").laid.n = 7; shared.n` ended the executable: exit 134,
"StoreOfOtherType of field n". A function returned so: "was not compiled into this executable".

* AOT: the run-time counters ask whether a VM still has instances

A VM's free lists are counted for its first instance, and `instances.first()` was read without asking whether the list
is empty. Where it is, the first of the instances that wait to be destroyed is taken. With a native test.

* AOT: `vi.doMock()` leaves alone what a test file has loaded, through two re-exports too

leaf.js: `export const x = "real x", y = "real y"`. barrel.js: `export { x, y } from "./leaf.js"`. barrel2.js:
`export { x, y } from "./barrel.js"`. user.js imports barrel2.js, reads, calls
`vi.doMock("./barrel.js", () => ({ x: "over x", y: "mock y" }))` and reads again: plain gives "real x" both times. One line.

* AOT: the road of an asynchronous mock factory checks its exceptions

Every `bun test --aot` run in which an import waits for an asynchronous mock factory
(`vi.doMock("./m.js", async () => { await ..; return {..} })`, then `await import("./late.js")`) aborted under
JavaScriptCore's exception-scope validator: "ERROR: Unchecked JS exception". An earlier commit of oven-sh/WebKit#974
brought…
* AOT: the key of a `for in` stored into a field crashed a very large executable

A crash at default flags in an executable above 4,194,304 values, and in test runs over layers. Bun's main has it too. In
AOTStringPasses.cpp. Two stored programs are in Bun.

* AOT: build time: two more quadratic costs under the limit on tested types

Behind each copied range of a block, PlaceTypeTests read the block's values one by one for the first point where the copy
may come back: ranges times values. And the greedy register allocator added up the moves on every edge of a loop though
the sum had passed the bound. No output changes.

Shared with the JIT: b3/air/AirAllocateRegistersByGreedy.cpp +14 -6. `forEachEdgeToWhereLive()`'s functor answers
IterationStatus, and its one caller ends the walk as soon as the sum has reached the bound. The costs are not negative.

* AOT: four more functions of the mocks behind the table

Behind "the run time reaches the mocks through a table that the host answers". Every name and call site stays; the bodies
move behind the table. No behavior changes.

* AOT: a read off a namespace object goes past no mock

leaf.js: `export const x = "real x", y`. barrel.js: `export { x, y } from "./leaf.js"`, loaded.
`vi.doMock("./barrel.js", () => ({ x: "over x", y: "mock y" }))`. barrel2.js: `export { x, y } from "./barrel.js"`, first loaded
now: `const m = await import("./barrel2.js")`. Plain gives "over x" however it is read; compiled code did not for `m.x`
and for a destructuring parameter. The raw output of four servers is identical.

* AOT: a deletion or a new prototype on a module's object through an unknown receiver is seen

* AOT: the mock of a module that is linked below mocks alone waits

l imports k imports j imports i. `vi.doMock('./k.js', ..); await import('./l.js'); vi.doMock('./j.js', () => ({ y: 'mock-j' }))`:
the mock of j never ended: behind `vi.doUnmock('./j.js')` an `import()` still answered "mock-j".

* AOT: the verifier's net answers for nothing behind three more passes

The rows of ConvertCountersToIntegers, RetypeValues and SplitUnions go out of the table of operations that a pass answers
for. Each let every operation through. Verifying builds alone.

* AOT: a mocked file of the program below counts

barrel.js: `export * from "pkg"; export * from "./clash.js"`, x in both. `vi.mock("pkg", () => ({ x: "mock x", f }))`.
`import * as ns from "./barrel.js"`: plain, and a run compiled as one program, give "mock x": the first star that has the name
gives it. Over layers, where the package lies in a program below the barrel's, it gave "clash x", without an error.

* AOT: refusals are counted where they are made

With `BUN_JSC_aotCountsPath` set, every error object whose sentence is one of the compiler's refusals is counted where it is
made, caught or not. A suite can pass while a library catches the refusal and takes another road.

Outside aot/: runtime/ErrorInstance.cpp +5, inside `#if ENABLE(AOT)` in `ErrorInstance::finishCreation()`. The option is asked
first, then `vm.hasCompiledCode()`: without the option a run reads the option and goes no further.

* AOT: a stand-in refuses a write

`import n from "node:fs/promises"; new Function(text)(); n.access("/")`, where text, out of the build's sight, is
`process.getBuiltinModule("node:fs").promises.access = () => "mine"`. So too `defineProperty`, `delete` and a new name. A
write to the stand-in of a member that was left out is refused.

* AOT: a built-in function is known by the name it was made with

A test file: `vi.spyOn(fetch, "preconnect").mockReturnValue("spied")`; a product file: `fetch.preconnect(url)`. Plain, and a run
compiled as one program, give "spied"; over layers: "TypeError: Cannot spy on 'preconnect' of a built-in function". So too
`Bun.fetch` and `globalThis.fetch`.

* AOT: the verifier's net answers for one opcode behind two more passes

The rows of EliminateTailRecursion and StartGeneratorsAtFirstStep answered for every operation that goes; now for
CallDirect alone. Only what `--aot-check=verify-each-pass` judges; no generated code changes.

* AOT: a reference to a value is not held across the insertion of a new one

`sayWhatStoresBehindFormerChecksHold()` in AOTEntryChecks.cpp held a `const Value&` into the function's values while it
inserted claims in front of the user. A claim is a new value, and the values move when one is added: a use after
reallocation in the compiler. The reference is fetched anew for each operand. An earlier commit of this pull request brought
it; found in review. No known program reads through the stale reference.

* AOT: the throw scope stands in the two arms of tryReplaceExport() that need it

`spyOn()` of an export that is not replaceable answers with a TypeError. Under JavaScriptCore's exception-scope validator the
compiled run ended by SIGABRT: "This scope can throw: tryReplaceExport .. unchecked as of this scope: spyOn". An earlier
commit of this pull request laid a throw scope over the whole function. It shows only with the validator on, as on Bun's
ASAN lane.

* AOT: a type test is typed by the operand it has

    function f(x, z) { let d = x; if (z === 1 && d < x) { } else { d = x; } return ((x + d) | 0) + (d | 0); }

A type test that was made over a value tested on one path only kept its answer when it was handed the value of every
path. On Bun's main the executable crashes on `f(1.5, 1.5)`. With a planted fault and a statistic.

* AOT: a mock that has ended stays for whoever was linked against it

`vi.doMock("./dep.js", f1); const { seen } = await import("./user.js"); vi.doMock("./dep.js", f2); seen()`: plain gives the
first mock's value, until something loads the module again. Compiled code gave the second's, without an error, and behind
"a second mock factory waits, as the first does": "Cannot access 'flag' before initialization".

* AOT: the compiler crashed on a RegExp made of `Object.keys()` of a literal, in a file required inside a `try`

    var table = { theme: b };
    function b(r) { r = c(r); }
    function c(e) {}
    exports.pattern = new RegExp(Object.keys(table).map(e => `${e}\\(`).join("|"));

`let m; try { m = require("tailwindcss"); } catch (e) {}` (tailwindcss 4.3.3): `bun build --compile --aot` ended by SIGILL:
"Stopped while compiling in CollectRegExpLiterals". Bun's main builds it. The list of what `Object.keys()` of a literal
answers asked for the key of every field of the literal's layout, and a field of a layout need not have a name. Such an
object is left alone now: the pattern is made at run time.

* AOT: a pass that has cut blocks says so

PlanArrayCapacities answered "unchanged" with blocks cut: it cuts the region of reads out and has two ways out behind the
cut that make no copy, and its caller counted a change only where there was a copy. The runner goes by that answer. With a
test in IR.

* AOT: the flow graph's helpers each take at least eight indices of a wave

Build time alone; no output of the compiler changes.

* AOT: the verifier's net answers for the accesses that ResolveAccesses declares

Its row answered for every operation that goes; now for the set that the pass declares for itself, by which the runner
decides whether it runs at all. Only what `--aot-check=verify-each-pass` judges.

* AOT: the verifier's net answers for the walks that ExpandOwnKeys expands

Its row answered for every operation that goes; now for the walks over own keys that the pass declares and expands:
CopyDataProperties, CopyObject, CallBuiltin. Only what `--aot-check=verify-each-pass` judges.

* AOT: the refusal of a changed built-in has a test that can fail

One condition in AOTValueFlowRulesHost.cpp on a planted fault that is there already. No output changes at default flags. The
test is in Bun.

* AOT: the namespace of a built-in module takes own properties alone

Behind "modules that hidden code fetches by name are held, not escaped": what flow analysis answered for one stored program
depended on the order in which its rules ran. One line.

* AOT: the verifier's net answers for what PlanArrayCapacities and ResolveAwaitedCalls work on

Their rows answered for every operation that goes; now for the seven operations that PlanArrayCapacities names as appends,
and for AwaitBySavingFrame, CallBuiltin and CallDirect behind ResolveAwaitedCalls. Only what `--aot-check=verify-each-pass`
judges.

* AOT: what the next test file sees of a file that stars what was mocked

barrel.js: `export * from "pkg"`, and pkg is mocked before the load by `vi.mock`. a.test.js and b.test.js both import user.js,
which reads barrel.js four ways. In b.test.js `require("./barrel.js").x` was undefined and `require("./barrel.js") === ns` false;
plain gives "real x" and true. With an ES package the value was right and the identity false.

* AOT: a user that is imported anew behind a mock reads the mock

dep.js and two users of it are loaded; `mock.module("./dep.js", ..)`; then `vi.doMock("./dep.js", () => ({ flag: "three", .. }))`;
then `(await import("./user-late.js")).values()`: plain gives three, three, three; compiled code gave real, real, real, without
an error.

* AOT: a module that is owed to an importer runs though the importer is mocked meanwhile

r.js imports m2.js imports x.js. Test file 1: `vi.doMock("x.js", ..)` ahead of its load, `await import("r.js")`: r and m2 run,
x's body doesn't; the mock ends. Test file 2: `vi.doMock("m2.js", ..)`, which has run, then `require("r.js")`. Test file 3:
`require("r.js")`, `r.read()`: plain gives "real x" and x ran once; compiled: "ReferenceError: Cannot access 'value' before
initialization", and x ran 0 times. Found in review of oven-sh#974.

* AOT: over layers, the second of two imports that wait for one asynchronous mock factory failed

`mock.module("./lib.mjs", async () => (await later(), { v: "mock v" }));
await Promise.all([import("./user.mjs"), import("./other.mjs")])`, both import lib.mjs: "Cannot access 'v' before
initialization". Plain, and compiled code as one program, hand both the mock. Bun's main has it too over layers.

* B3: only pointers from outside may be promised dereferenceable

B3's validator refuses a promise of dereferenceable bytes on a value that is computed from others, as it already does for
known ranges; under B3's default policy no promise is ever stored, so the new line is never reached in the JIT.

Shared with the JIT: b3/B3Validate.cpp +3 -1, b3/B3KnownProperties.h, and two testb3 files.

* AOT: the table of the states of a mock, second edition

What the observer of a mock's states reports, not what a mock does: "left to the host" is said beside the body's status, and
two states are new: `in place while another waits` and `fills`.

* AOT: a file that was linked before `vi.doMock` of a CommonJS file keeps the real values

old.js: `import { who } from "./m.cjs"`; the test: `import { read } from "./old.js"; vi.doMock("./m.cjs", () => ({ who: "mock" }));
read()`. Plain: old.js keeps `real`; import() and require() by name, and a file linked behind the mock, get the mock; the factory
runs at the first load that comes to it. Compiled: the factory ran at the call and its values were laid over the copies that ES
importers read, so everybody read the mock, and the namespace object kept the file's names. Without an error.

* AOT: a package behind two files that only hand names on runs for the next test file

node_modules/pkg/index.js: `export const x = "real x"`; src/inner-names.js: `export { x } from "pkg"`; src/names.js:
`export { x } from "./inner-names.js"`; src/uses.js imports x and the namespace of names.js. a.test.js mocks pkg before the load;
b.test.js mocks nothing and imports src/uses.js. Plain: `real x`; compiled: "ReferenceError: Cannot access 'x' before
initialization". With one file between it was right.

* AOT: over layers, a mock of a module that the loader had let go was not seen

reader.mjs: `import { ofBody, real } from "./above.mjs"`. a.test.mjs mocks leaf.mjs and imports reader.mjs. b.test.mjs:
`mock.module("./body.mjs", () => ({ ofBody: "mock of body" })); (await import("./reader.mjs")).read()`. Plain:
`mock of body undefined`; compiled, over layers: `of body real`. As one program it was right. Behind "what the loader has let go
is mocked ahead of its load".

* AOT: a name that a mock gives ahead of the load of a compiled module makes nothing ambiguous

A barrel that re-exports the same name from two modules lost that name under `bun test --aot` once one of them was mocked ahead
of its load; plain `bun test` gives it the first module's, as Vitest does. A mock laid over a module that has already run leaves
the name ambiguous, as in plain.

barrel.js: `export * from "./clash.js"; export * from "pkg"`, x in both; `vi.mock("pkg", () => ({ x: "mock x", f: "mock f" }))`;
`import * as barrel from "./barrel.js"`. Plain: `x=clash x`, keys f, other, x. Compiled: `x=undefined`, keys f, other, without an
error. Over layers, with the package, the next test file: plain `x=undefined`, ambiguous again; compiled `x=clash x`.

Outside aot/: runtime/AbstractModuleRecord.cpp, inside `#if ENABLE(AOT)`, in ResolveExport's merge: one read of
vm.hasCompiledCode(); the rest is a function of its own that a run without compiled code never calls. On 40,000 ambiguous names a
plain run's instructions are level.

* AOT: a user that is required anew behind a mock reads the mock

As "a user that is imported anew behind a mock reads the mock", but the user is required:
`import.meta.require("./late.js").values()`, behind an import() of the mocked module. Compiled code gave real, real, real,
without an error.

* AOT: a package that imports a mocked ES module keeps the real one

node_modules/reads/index.js: `import { value } from "dep"; export const seen = () => value();`; the test:
`import { seen } from "reads"; vi.mock("dep", () => ({ value: () => "mocked" }))`. Plain: `real`, as Vitest leaves packages as
they are; compiled: `mocked`.

* AOT: the asynchronous mock factories of one load take turns

`vi.doMock("./k.js", async () => { say("k begins"); await later(40); say("k ends"); return { k } });
vi.doMock("./m.js", async () => { .. later(5) .. }); await import("./a.js")`, and a.js imports k and m. Plain: k begins, k ends,
m begins, m ends; compiled: k begins, m begins, m ends, k ends. Also a factory that answers at once between two that wait,
factories at different depths, and `vi.mock` below a statement of the test file.

* AOT: with assertions on, the reader makes no checked number out of an unchecked word, and two tests use numbers that a stamped number can hold

Behind "in a build with assertions a value's number says which renumbering handed it out": four native tests ended by an assertion in every build with
assertions. A release build compiles the same code as before.

* AOT: a native test calls its operation from an entry frame

compact-table/ordinary-table-has-no-prefix called operations that are no leaves straight from C++ and ended by an assertion in
builds with assertions. A test alone.

* AOT: a trimmed executable keeps the run-time operations that its image lists

The run-time table takes the address of all 518 operations that compiled code may call, so each stood in every executable with
all that it reaches, though an image lists the entries that it uses. 356 operations are now in 39 families by what they are for
(proxies, typed arrays, private names, import(), maps and sets, object spread, generators ..), each a feature that only the list
of an image keeps. An operation that nobody names there stays in every executable, so whoever adds one need do nothing.

Goes with Bun's src/trim/features/engine.def: the two lists must agree, or neither builds.

* AOT: the original that a mock factory asks for brings what is owed below it

a.test.mjs: `mock.module("./leaf.mjs", () => ({ leaf: "mock leaf" })); await import("./first.mjs")`. b.test.mjs:
`vi.doMock("./body.mjs", async importOriginal => ({ ...(await importOriginal()), ofBody: "mock of body" }));
await import("./above.mjs")`, body.mjs > dep.mjs > leaf.mjs by `export *`. Plain passes; compiled: "ReferenceError: Cannot access
'leaf' before initialization." out of the spread.

* AOT: build time: the exit of an integer update in memory is kept where it is found

In updateIntegersInMemory() each update that is applied invalidates the graph of blocks, and the next one asked for the exit that
dominates it, so B3's dominators were made anew for each update, to find an exit that the search for updates had already found:
updates times blocks. An update now holds each user with its exit, taken while the dominators hold. x86-64. No output changes.

* AOT: over layers, `vi.doMock` reaches a module that an earlier test file loaded by import()

dep.js: `export const value = "real"`. subject.js: `import { value, get } from "./dep.js"; export const f = () => [value, get()].join()`.
f1.test.js, no mock: `const { f } = await import("./subject.js")`. f2.test.js:
`vi.doMock("./dep.js", () => ({ value: "mocked", get: () => "mocked" })); const m = await import("./subject.js"); m.f()`.
Plain, and compiled code as one program: `mocked,mocked`; over layers: `real,real`, without an error.

* B3: what foldPathConstants rewrites by a fact of one path forgets what was promised about it

foldPathConstants replaces an operand by what a branch proved on one path. A value changed so kept the facts the compiler was told
about it ("these bytes can be read", "it lies in this range"), which are meant to hold wherever the value is computed; hoisted off
that path, a load from it could read address 0. Now such a value, and what is computed from it and may move, forgets those facts.
No compiled program changes: identical machine code on 408 programs, 1.37 million functions.

Shared with the JIT: b3/B3FoldPathConstants.cpp. All hunks but one lie inside our own class FoldPathConstantsInValueOrder, which
the JIT never makes; the one on the JIT's road adds `|| !proc.knownProperties().isEmpty()` to the condition in foldPathConstants()
that chooses the class: under B3's default policy setKnownRange() and setKnownDereferenceableBytes() store nothing, so the table
is empty, the condition reads as before and upstream's class runs.

* AOT: under `--aot-check=verify-each-pass`, SinkAllocations says why a test for an object goes

`for (const n of source) if (n === 4) break;` beside a module with `class Pretender extends Iterator`: "verification failed after
SinkAllocations; v49 (RequireObject) in b18 may throw or run code, and is gone". It could not have thrown: the pass lets a cast go
only where every variant of an object that it holds passes it. It now says so. A build without the flag compiles what it compiled.

* AOT: under `--aot-check=verify-each-pass`, a pass that answers "unchanged" has changed nothing

What a pass answers decides what the runner does behind it: it drops analyses and gives other passes work only behind "changed".
Where every pass is verified, a run that answers "unchanged" is now held against the body as it was. One pass over strings that
the rule still accused is cured. With a planted fault, PassesChangeNothing, and its witnesses in Bun. No function's machine code
changes.

* AOT: a mock without a factory is made of what the original exports, with what is owed below it

a.test.mjs: `mock.module("./leaf.mjs", () => ({ leaf: "mock leaf" })); await import("./first.mjs")`. b.test.mjs:
`vi.doMock("./body.mjs"); (await import("./body.mjs")).leaf`, body.mjs > dep.mjs > leaf.mjs by `export *`. Plain: `real leaf`;
compiled: `undefined`, without an error. A sibling of "the original that a mock factory asks for brings what is owed below it".

* AOT: the key of a `for in` over number keys and computed names crashed a very large executable

Behind "the key of a `for in` stored into a field crashed a very large executable", which missed every name that is neither a
field's key nor an operation's: an index (`{ 200: .. }`), "true", "null", "undefined", NaN, Infinity, a computed name. A crash at
default flags in a very large executable; on Bun's main a wrong answer without an error. A member of a type that the program
hands on and nobody spells is no longer left out of the table of texts. 33 more stored programs are in Bun.

* AOT: two modules that import each other, both loaded by import() calls in one turn, failed in a test

Two modules that import each other, both loaded by `Promise.all([import("./a.mjs"), import("./b.mjs")])` in a test, failed with
"Cannot access 'fromB' before initialization". The change that ordered two held import() calls by their last shared file is taken
back. Three lists of known differences in Bun go with it.

* AOT: test files that the front end has read are no hidden text

With test files run from disk, an export that no test file takes, on a file that a test spies on, was readable where the run
refuses it ("Cannot read the export 'usedByNobody' of .."). Behind "modules that hidden code fetches by name are held, not
escaped": the imported `spyOn` also held the unknown object, so the namespace that it was handed escaped, and every export with it.
* AOT: the planted faults that drop an operation reach passes over the whole program, and a second one drops stores

Under the planted fault, the check behind a pass over the whole program is shown a copy of the first body that has such an
operation, without it; the program and every later verification are as they were. A second word, PassesDropStores: a store by name
goes. Only under `--aot-check=verify-each-pass` with a planted fault. Witnesses are in Bun.

* AOT: no warning about an import path where the build has read every name

`import(new URL("./x.mjs", import.meta.url))`, the same with .href, `import(import.meta.resolve("./x.mjs"))`,
`const n = ["a"][0]; require(`./lib/${n}.js`)`, `require(["./chi", "ld.cjs"].join(""))`,
`require(path.join(__dirname, "plugins", name + ".cjs"))` over a literal list, `import("node:" + ["process"][0])`: each warned
TS100064 "this import path isn't a constant. If it resolves to code that isn't in the executable, the import throws at run time",
though the build had read every name.

* AOT: the original that a mock factory takes of a package is the package's own compiled code

a.test.js: `vi.doMock("pkg", async importOriginal => { const original = await importOriginal(); globalThis.original = original;
original.inc(); return { ...original, a: "mock" }; })`; z.test.js mocks nothing and imports "pkg". `pkg.fn === original.fn`,
`pkg.count`: plain true, 1, and the body runs once. As one program: false, 0, and the body ran twice. Over two layers: true, 1, but
by the copy from disk, interpreted.

* B3: in versionLoops a value that another block uses was taken for a Phi of the loop's header

A wrong answer without an error. The cloner turns every Phi of the region into Identity(Get(variable)), and every value that
another block uses into a variable too; variableOfHeaderPhi() told a header's Phi by that look. A plain Identity(x) left in the
header, x a hoistable value of the loop that another block uses, looked the same: x's variable was read in front of the fast loop,
where nothing had set it, and that read stood in x's place in the whole fast loop. A variable with a single definition is no Phi of
the header. Found by testb3's random programs.

Shared with the JIT: b3/B3VersionLoops.cpp +3 -2. The phase runs only where `policy().loops.versions` is set; it is false by
default, and the JIT does not set it.

* AOT: the verifier's net is narrow behind three passes over the whole program

SplitFreshResults answered for every operation that goes; now for CallDirect alone. MoveGeneratorFramesToHeap: for
YieldBySavingFrame alone. The row of RemoveUnreachableFunctions is deleted: the pass takes whole functions away and nothing out of a
function that stays. Only what `--aot-check=verify-each-pass` judges. A red control for each is in Bun.

* AOT: six counts of the checker's queries are rows of the table of limits

MaxConstructorParentsFollowed 64, MaxHelpersFollowedToPrototypeLink 8, MaxFunctionsGivenThis 32, MaxCallsReadForParameter 16,
MaxTermsReadForProduct 16, MaxDeclaredSignatureDepth 3: bare numbers in Bun's sources until now, with the values they had. Goes
with Bun's half.

* AOT: the image says which async functions hold no await of their own

The host asks it of the factory of a mock: inside a require() a factory that awaits is not called. For a function that the engine
compiles, the parser answers. A compiled function has no executable, so the front end's flag goes into a sorted table of the
program, and awaitsByItself() looks the function's source up in it. Goes with Bun's half, which calls it.

* AOT: the verifier's net is narrow behind InlineHeads

Its row answered for every operation that goes; now for CallDirect alone: the pass puts the head of a known function in place of a
call of it. Only what `--aot-check=verify-each-pass` judges. A red control is in Bun.

* AOT: whoever holds a module that was linked to a mock keeps that mock

held.js: `import { who } from "./dep"`; the test: `vi.doMock("./dep", () => ({ who: "one" })); const held = await import("./held.js");
vi.doUnmock("./dep")`, or a second vi.doMock(); `held.read()`. Plain: `one`, for as long as held.js is held. Compiled: on a CommonJS
file `undefined` at once, neither the mock nor the file; on an ES module, a CommonJS file and a package, the real module or the
second mock behind the next load by name. All without an error.

* AOT: under the address sanitizer, a reference held across a call that moves its table is stopped at once

Under the address sanitizer, a function that was run for the parts of an IR record reads the record once more, lists grow by one
element, and the table of functions moves at every append, so that a reference held across a call that moves its table is stopped
at once. With tests.

* AOT: an import waits for a mock factory that has started

One line in Modules::importUncompiled(). Its test, mock-original-fails.test.ts, is in Bun and is red without it.

* AOT: build time: two quadratic costs in PlaceTypeTests, and one where a loop holds many comparisons

A function with thousands of `x !== x` and of type tests, such as 20,586 loops `while (a !== a) a = [a];`: the graph was made anew
behind each cut, and a failed test was looked up in a list. And `for (..) { if (k > 0) ..; if (k > 1) ..; .. }`: for every relational
comparison all blocks of the loop were walked before it was asked whether the comparison tests one of the loop's counters:
comparisons times blocks. No output changes.

* AOT: build time: the walk that feeds a built-in that walks its argument has a statement of its own

The solve of flow analysis grew worse than a square on a chain of objects handed to a built-in that walks it, such as
JSON.stringify or console.log. The solver makes a statement that has run often wait while any other can run, and the walk that
feeds such a statement was part of that same statement, so at every level of the objects nothing else was due.

* AOT: a request to terminate a Worker waits behind an entry file that has run

`const w = new Worker('require("worker_threads").parentPort.postMessage([1, "two"])', { eval: true });
w.on("message", m => { resolve(m); w.terminate(); })`, in the company of a large project, in a build with assertions: "ASSERTION
FAILED: module->evaluationError() == exception->value()", runtime/CyclicModuleRecord.cpp, evaluate(). About one run in seven.

* AOT: `vi.spyOn(Bun, "origin", "get")` was refused

`vi.spyOn(Bun, "origin" | "isStandaloneExecutable" | "version_with_sha" | "ModuleGraph", "get")` answered "TypeError: Cannot spy on
Bun.origin because built-in objects are read-only in compiled code, and a test can't replace this one: it is read without being
looked up"; `bun test` makes the spy. As one program at default flags too, as soon as a file of the project uses Bun at all. A member
that changes on its own is locked by no image.

* AOT: a store under a key that the build doesn't know enters a setter that deletes a field or calls a method

`import "node:util"; class C { z = 0 } const KEY = JSON.parse(..); function run(given) { const o = given ?? new C();
Object.defineProperty(o, "p", { set(v) { delete this.z } }); o[KEY] = 1.5; return o.z } run(); run([])`: `bun run` prints undefined,
undefined; the executable ended with exit code 134: "DeleteField on an object of layout 0 (C), which the compiler assumed never
happens". And with `set(v) { this.bump() }`: "`bump` was not compiled into this executable because nothing that the compiler can
follow calls it".

* AOT: a sliced or joined string typed as a union of string literals, as a Map or Set key, crashed or missed the key

`type T = "red" | "green" | "blue"; const map = new Map<T, number>([["red", 1], ["green", 2], ["blue", 3]]);
function use(x: T) { return map.get(x); }
for (let i = 0; i < 4; i++) console.log(use(i === 2 ? (text.slice(1, 6) as T) : "red"));` with a text that the build doesn't know:
plain prints 1 1 2 1; the executable crashed at the third line. With `(part + "em") as Unit` the key was missed. Map.has and Set.has
alike. At default flags.

* AOT: the verifier's net answers for what ResolveBuiltins resolves

Its row answered for every operation that goes. Only what `--aot-check=verify-each-pass` judges.
…port() in test runs (oven-sh#982)

* AOT: a counter of which call of a mock meets which state

AOT::countMockCall() returns at once unless the path for counts is set. It changes no answer. Goes with Bun's half, which calls it.

* AOT: `vi.stubGlobal` defines its name on the global object however its function travels

lib.js: `export const read = () => typeof someGlobal`. A test: `run(vi.stubGlobal)` with
`export const run = f => f("someGlobal", "stubbed")` in another file; `[vi.stubGlobal][0]("someGlobal", "stubbed")`;
`const held = { stub: vi.stubGlobal }; held.stub(..)`. Plain: `string`; compiled: `undefined`, without an error. Also through a
static field, an instance field, a Map, a generator, Object.values, a spread, a closure of another file. Goes with one word in Bun's
table of built-ins.

* AOT: under `--aot-check=verify-each-pass`, a body that is split tells the check

With --aot-check=verify-each-pass, the pass that splits a function behind its entry checks tells the check that the function's body
was replaced. The check compared the old body with the function that tests the arguments, and a build with assertions stopped there.

* AOT: under `--aot-check=verify-each-pass`, a function that a pass leaves without values is looked at

The check compared nothing where the body behind the pass had no typed value: meant for bodies that are not typed yet, it also held
for a body without any value, so a pass that empties a function was seen by nobody. A red control is in Bun.

* AOT: five points of a review of oven-sh#978

- Under `--aot-check=verify-each-pass`, the check of a pass that answers "unchanged" held the numbers of blocks against each other and
  not the numbers of values: a value in no block went unseen. With two planted faults; their witnesses are in Bun.
- In updateIntegersInMemory() a user that is listed already is the last one listed, so the search through the list goes.
- In isSettledByMock() two operands without effects change places, the cheaper one first.
- The counter of refusals tells a refusal by longer parts of the run time's own sentences: a program may well say "compiled code" itself.
- A native test compares the bits of two numbers of values.

No generated code changes. Outside aot/: runtime/AbstractModuleRecord.cpp +1 -1, in a function that a run without compiled code never
calls.

* AOT: an unsigned number wrapped in holdText() where a text's turn had passed

Found in review of oven-sh#978. A text whose turn has passed adds no levels. Its test, chained-imports.test.ts, is in Bun: it
observes the order in which chained import() calls settle.

* AOT: `--explain=statistics` counts the Map and Set lookups emitted in line, and `--explain=missed-optimizations` names some

Three rows: InlineHashLookups, TagLookupsWithConstantKeys, TagLookupsWithOtherKeys. The sites of the third are named: "missed:
lookup-key-not-constant at <file>:<line>:<column>". Goes with Bun's half.

* AOT: a call on the first of two objects of a constructor function went to the prototype that the second was made with

Two objects of one constructor function in one function, the function's `prototype` replaced between them and put back:
`const q = new Q(); Object.defineProperty(Q, "prototype", { value: second }); q[key] = 1; const r = new Q(); ..put back..;
q.describe()`: plain "first", compiled "second", without an error, at default flags. The step of ThreadJumps that sent an unlikely way
past the next test of the class whose object it made is taken out.

* AOT: a view behind `memory.toResizableBuffer()` kept its old length

`const bytes = new Uint8Array(memory.buffer); memory.toResizableBuffer();` and then `bytes.length`, `bytes[0]`: `bun run` prints
`0 undefined`; compiled `65536 9`. A loop over bytes made 65,536 turns for 4; a loop of six turns crashed. The row of the table of
built-ins that toFixedLengthBuffer and toResizableBuffer share did not say that it writes the storage of typed arrays.

* AOT: the store of a sort in place names the elements of every form of storage

The library sorts a short list where it lies, and takes storage of int32 for contiguous storage on purpose. The store named B3's heap
of contiguous elements alone, which B3 holds disjoint from that of int32 elements, so a read `a[i]` under the other name could have
been carried across it.

* AOT: a CommonJS file that an import() call names runs in its turn

`const [a, b] = await Promise.all([import("./a.mjs"), import("./b.cjs")])`: in node and in `bun build --compile` a.mjs runs first;
compiled ahead of time, b.cjs did. Where b.cjs has `require("./a.mjs")` and a.mjs calls `import("./b.cjs")`: the keys of b are
`default,fromB`; compiled `default` alone, and b.fromB undefined. Two lists of known differences in Bun get shorter with it.

* B3: a decoded narrow cell may be promised dereferenceable

The validator's rule for a promise of dereferenceable bytes also takes Add(ArgumentReg, Shl(ZExt32(y), constant)) with y no constant.
Found in review of oven-sh#978.

Shared with the JIT: b3/B3KnownProperties.h +8 -2. Under B3's default policy no promise is ever stored, so the rule is never asked in
the JIT.

* B3: a copy that threadJumps makes for one way in forgets what was promised about it

threadJumps copies a tail for each way in and puts the Phi's input for that way in the Phi's place; the copy kept the promises that
were made of the Phi. A pure value of the copy is loop invariant then, and was hoisted with its load above the test that chose the
way. A graph written by hand: 70 at level 0, a crash at level 2.

Shared with the JIT: b3/B3RegionCloner.cpp +18 -2, B3RegionCloner.h +2, B3ThreadJumps.cpp +1 -1. The cloner is used by threadJumps,
rotateLoops, versionLoops and unrollLoops alone; each runs only under a field of the policy that is false by default and that the JIT
does not set.

* AOT: a direct eval has a family of its own among the run-time operations

main.ts `console.log(eval(process.argv[2]))` built with --disallow-code-generation-from-strings: `bun check --aot` said that the
executable keeps the feature "Interpreter", which it used to leave out. A matter of size, not of what the flag forbids. Behind "a
trimmed executable keeps the run-time operations that its image lists". Goes with Bun's src/trim/features/engine.def.

* AOT: the observer of the states of a mock, third edition

What the observer reports, not what a mock does: a built-in module under a mock said `none`; now `in place` where the mock replaces it
and `laid over` where the loader held it. A new state: `ended while another waits`. Goes with Bun's half.

* AOT: build time: the walk that feeds a built-in that walks its argument asks what is new

Behind "the walk that feeds a built-in that walks its argument has a statement of its own". Each round the walk's statement asked the
same reads of a set one member larger, so the solver let go of every node asked for before and took the new ones up: each part four
times as dear at a doubling, on a build of 4,000 chained literals. No answer of flow analysis changes.

* AOT: under `--aot-check=verify-each-pass`, a pass that moves a function's body without saying so stops the build

With --aot-check=verify-each-pass, a pass over the program that moves a function's body into another function without saying so stops
the build, which names the pass and the function. Before, the check compared the old body with whatever took its place. With a
sabotage and a pair of tests.

* AOT: over layers, the next test file read a mock that had ended with the first

a.test.js: `mock.module("pkg", ..); const { seen } = await import("./src/uses.js")`. b.test.js: `import { seen } from "./src/uses.js";
seen()`. uses.js: `import { f } from "pkg"; export const seen = () => f()`. Plain: `real` in b.test.js; compiled, over layers:
`mocked`, without an error.

It came with "whoever holds a module that was linked to a mock keeps that mock" (oven-sh#979): five lines of that commit, in
AOTModules.cpp, are taken back.

* AOT: a flat string has a type of its own in the emitters

StringEmitter::implOfFlatString() loads the text of a string's cell with a load that is marked immutable and promised dereferenceable.
It took any pointer to a cell, and the emitter of Map and Set lookups handed it a sliced or joined string because the type held only
literal strings ("a sliced or joined string typed as a union of string literals, as a Map or Set key, crashed or missed the key"). It
now takes a FlatStringCell, which only three functions make, so that the mistake does not compile.

* AOT: two layouts that are made equally often are ranked alike

Where more layouts have the names asked of an object than there is room to test for, they are ranked, last by how often each is made:
a sum of products over the whole program. Two layouts made equally often could come out one rounding error apart, and the last digit
chose which of them is tested for: five lines in a library file moved twelve functions of unrelated packages. The key is cut short of
its last digits.

* AOT: a read of a string whose result has no room for "outside" is refused, not compiled unchecked

Six branches read a string with no test of the position where the result's representation has no room for the answer to a position
outside it (NaN or undefined): charCodeAt, codePointAt, at and the reads of a range. Nothing makes such a type today, so they were dead
code; the build now stops there instead.

* AOT: what a refused spy or mock says in a test run

`TypeError: Cannot spy on 'answer' because module exports can't be replaced in a compiled executable` and `mock(module, fn) cannot
replace a module that was compiled ahead of time: "<path>"` are what a user meets where the build missed a spy or a mock. In
`bun test --aot` there is no executable, and exports can be replaced; the first named no module, and neither said what to do. The engine
words both now, by the kind of run. Goes with Bun's half.

* AOT: no direct call where an argument cannot be what a predicted callee takes

An untyped file holds `box.run.call(AbortSignal, [controller.signal])`, `box` defined by nobody; a typed file of the same build has
`class Holder3 { run(given: number[]) {} }` and one call `run([5, 6, 7])`. The build stopped: "verification failed after ResolveCalls;
StoredTypeMismatch .. (AssumeType)", at default flags.

* AOT: two assumptions are written down where they would break

Compiled code makes the size of a table's index as `2 << shift` in 32 bits; the shift is 31 above 201,326,592 entries. The run time now
stops where it grows a table past what the walk in line can address. No cost in compiled code. And one in SinkAllocations.

* AOT: a getter that escapes and adds, deletes or freezes a member of `this` ended the executable

`class Row { port = 80 } function peek(base) { const target = base ?? new Row(); Object.defineProperty(target, "value",
{ get() { this.seen = 1; return 1 } }); target.value; return typeof target.seen }
console.log(peek(), peek(Object.defineProperties({}, JSON.parse("{}"))))`: plain `number number`; the executable ended with exit code
134: "AddProperty of seen on an object of layout 0 (Row), which the compiler assumed never happens". Also where the getter deletes a
member, freezes `this`, or fills a memo by `??=`. The twin of "a store under a key that the build doesn't know enters a setter that
deletes a field or calls a method".

* AOT: a planted fault that drops an operation is used up only by a drop that is reported

Behind a pass over the whole program the planted fault was used up at the first body where a drop was made, also where the check has no
word for it, and no later body was tried: a red control could show nothing. Found in review. Only under
`--aot-check=verify-each-pass` with a planted fault.

* AOT: over layers, the mock of one test file leaked into the next

dep.js lies in a lower layer than user.js and has run. a.test.js: `vi.doMock("./dep.js", () => ({ flag: "one" }));
(await import("./user.js")).read()`: one. b.test.js, the next file, mocks nothing and imports user.js again: plain `real`; compiled
`one`, without an error. Within a file too: behind vi.doUnmock() or a second vi.doMock(), an import() of user.js anew went on reading
the first mock. `bun test` takes whoever was linked to a mock out of its loader when the mock ends, and a load that comes by makes it
anew; a user above a mocked file is now linked anew where `bun test` loads it anew.

* AOT: under `--aot-check=verify-each-pass`, a store behind a check that nothing passes stopped a build

The verifier does not hold a value against the declared type of the place it is stored into where the value comes from a check that
nothing passes: the code behind such a check runs in the generic version alone. `held = value` behind `value instanceof Kind` in a
function called with .call() stopped a build under --aot-check=verify-each-pass.

* AOT: `--aot-validate` refused valid programs with "internal compiler error": UpcastNotSubset after PlaceTypeTests

PlaceTypeTests copies a loop into a fast and a slow one and lays a test of the type on the way back into the fast one; what the test
leaves of an array's type had lost the array's proofs, and an upcast behind it was not typed anew, so its source no longer lay inside
the type it casts to. The verifier's rule is right; the IR was inconsistent. Bun's main has it too. Its test is in Bun.

* AOT: two points of a review of oven-sh#979

- FailedTests sizes its set once, where there is a failed edge or switch at all.
- The native test of the net for held references, in builds with the address sanitizer, took any crash and any failed check of its
  child for "stopped"; it now asks for "AddressSanitizer: heap-use-after-free" in the output.

* AOT: a whole number that the engine boxed as a double was stored as an int32

`const row = [9.5, 0.5, 2, 3].slice(0); row.push("label"); function look(x) { const list = [1]; if (typeof x === "number" &&
(x | 0) === x) list.push(x); return list[0] + list[list.length - 1]; } look(row[2])`: `bun run` prints 3, compiled 0, without an error.
The same for `list.push(x, x)`, `[1, x]`, `[x, x, x]`; list.join() was right, every read in line wrong. Bun's main has it too.

* AOT: two IR tests in place of stored programs

The table-driven test of TryPutElements gets the two cases it lacked: storage for doubles is handed texts or objects. A new test of the
effects of a memory's kept buffer. Tests alone; eight stored programs go out of Bun with them.

* AOT: `bun test --aot` as one program settles import() calls as the executable of the same files does

A test run took another road than the executable for import() calls, so the two settled them in different orders: over four tables of
module graphs, 6,870 cells parted; now none. No cell of an executable changes. Where the executable is wrong today, the test run is now
wrong in the same way. Goes with Bun's half: never one without the other.

* AOT: a package that got the original read a preload's mock after it had ended

The preload: `vi.mock("dep", () => ({ value: () => "preload" }))`, `import "./own.js"` (a file of the project that imports "dep") and
`import { seen } from "reads"` (a package that imports "dep": under vi.mock() it gets the original). a.test.js: `vi.doUnmock("dep");
await import("dep")`. b.test.js: `seen()`, the package's first read. Plain: `real`; compiled: `preload`, without an error.

It came with "whoever holds a module that was linked to a mock keeps that mock" (oven-sh#979). The set of importers that got
the original was cleared at every test file's beginning, while the ended mock of a preload outlives the file; it is never cleared now.

* AOT: the number of uses from which a property name gets a stub of its own is a row of the table of limits

From 512 reads, stores or definitions of one name on, program-wide, the name gets the shared by-name code once more with its number
bound. The 512 stood outside the table, so it could not be lowered, and no small program and no fuzz lane ever ran that code. Now
MinUsesForOwnStub, with the value it had. Goes with Bun's half.

* AOT: the program's first generator ended the executable where a prototype had got an indexed property

`class B extends Array {}` made once through `new Proxy(B, {})`; `Object.defineProperty(V3.prototype, "0", {})`, then the same on its
parent's prototype; then the program's first generator object: "panic(main thread): abort() called", exit code 134. Plain is right.
Generators of a function that nobody has asked for its `prototype` share a stand-in for it; compiled code compares with a structure that
is recorded when the program starts, and the stand-in was made at the first generator. It is made of the recorded structure now.

* AOT: over layers, a barrel kept the names of a mock into the next test file

dep.js: `export const flag = "real"; export const plain = "real";`. barrel.js: `export * from "./dep.js"`. user.js:
`import * as barrel from "./barrel.js"`. The first test file: `vi.doMock("./dep.js", () => ({ flag: "one", plain: "one", added: "added" }))`,
then import() of user.js. In the next test file, which mocks nothing, `barrel.added` read "added" for undefined, and Object.keys(barrel)
`added+flag+plain` for `flag+plain`. With `export * from "./dep.cjs"`, `barrel.flag` read `one` for `real`. Without an error; as one
program it was right. Behind "over layers, the mock of one test file leaked into the next".

* AOT: the mocks that a helper laid are laid again for the next test file that imports it

helper.js: `vi.mock("./tax.js", () => ({ rate: "mock" }))`; a.test.js and b.test.js import it; z.test.js doesn't. Plain: a mock, b mock,
z real. Compiled: a mock, b real, z real, without an error, at default flags, as one program and over layers, with all five functions
that mock. `bun test` undoes a test file's mocks at its end, evicts the modules that laid them, and runs them again for the next file
that imports them. A compiled body runs once, so the calls are recorded and made again.

* AOT: `prev2 = prev; prev = cur` in a loop gave prev2 the new prev

`prev2 = prev; prev = cur; cur = cur + 3` in a `while`, over texts, in a cold or long function: a33|a33|a333 for a3|a33|a333, without an
error. Bun's main has it too. Where the test in front of a loop fails on a back edge, PlaceTypeTests defines the header's parameters
again, one behind the other in one block, and the repair of SSA took a use behind a definition for a use of that definition: a parallel
copy done in sequence. Every parameter that is handed on as another is now read before the first is defined again.

* AOT: a read that throws inside `try` in a loop over `[[], {}]` ended the executable

`try { for (const e of [[], {}]) try { e.x.y; } catch {} } ..`: exit code 133. Bun's main has it too. Where type propagation cuts a block
behind a value that never comes, the failing side went, with the read that throws; the probe in front of it throws nothing, and control
ran into Unreachable. A probe behind which the code is cut becomes the full read, which throws into the handler.

* AOT: under `--aot-check=verify-each-pass`, a handler that only threw on is said to go

"verification failed after Select; .. (PropGet) .. may throw or run code, and the handler of its block is gone": a read of error.name in
a `catch` whose handler is a `finally` that only pushes onto a list of the function's own. The pass is right: first the dead list goes
with its push, then the handler only throws on. It now says so. A build without the flag compiles what it compiled.

* AOT: `--aot-validate` refused a valid program: a function given by one caller, a Proxy over a function by another

`const o = { m: f }; return o.m();` given a function by one caller and a Proxy over a function by another: "StoredTypeMismatch" at a
NewObject, "after ResolveBuiltins; function 'use'". The verifier's rule is right: the failing body is the version of the callee for
callers that pass some function, and its parameter's type named a class where the Proxy goes by its name.

* AOT: README: whoever moves an allocation asks about the guards

Two sentences: a pass that moves an allocation asks creationMayBeOrderedWithGuards() and guardsOrderedWithCreation(), as SinkAllocations
does; a NewObject without a prototype operand takes the constructor function's prototype when its site first allocates, and the
operation's effects do not say so.

* AOT: a module stays mocked where the next mock already waits

A mock that has ended stays in place while the next one waits. When a load then let go of it, the module went out of the set of mocked
modules, though the next mock had put it there: a mock waited on a module that did not count as mocked, until its factory had run. No
line of the mock sequences changes.

* AOT: a validating build tests at run time that a flat string is flat where it is opened

Behind "a flat string has a type of its own in the emitters": the one place where FlatStringCell trusts its caller is checked in a
validating build, which names the operation that is being generated. With a planted fault, RopesPassForFlatStrings; its witnesses are in
Bun.

* AOT: one value under two local names, tested by truth, lost its null

`function f(a, b = a) { if (!a) { if (b === a) seen.push(a ?? "default"); b ^= 1; } else a == b; return b?.[0]?.[0]; }` called with -1, 1,
"", "1", null: plain `,default`, compiled `,null`, without an error. With `seen.push(b === a)`: true,false for true,true. Another form
ended the executable with exit code 133. Bun's main has it too. PlaceTypeTests laid a cast to an operand's type that claimed more than
was tested: of 288 variations 95 were wrong.

* AOT: every source under aot/ compiles alone

47 of 967 sources did not compile by themselves: they leaned on whatever stood in front of them in a bundle of 8 or 16, so a new file that
shifts the bundles could stop the build in a file that nobody had touched. Includes and a few names, in 36 files. Found in review of
oven-sh#979. No generated code changes.

* AOT: behind vi.resetModules() a failed import fails again in the same words

Behind `vi.resetModules()` the second and every later `import("./wants")` of a file that imports what isn't there failed as
`BuildMessage: ENOENT reading "not-installed"`; plain says `ResolveMessage: Cannot find package 'not-installed' imported from ..` each
time. In `bun test --aot`, at default flags, as one program and over layers. The loader forgets a kept failure with the importer's entry,
while the compiled record stays as it is; the failure is kept for such a request now.

Outside aot/: runtime/JSModuleLoader.h +1, inside `#if ENABLE(AOT)`: `hasResolutionFailure()`, an inline const question about a table
that the loader has already. Only aot/runtime/AOTModules.cpp asks it.

* AOT: build time: one question for all receivers first

Behind "a getter that escapes and adds, deletes or freezes a member of `this` ended the executable", which made a build quadratic: at
every read whose answer holds an unknown value the receivers that have not escaped were told apart, and each group's own chain was asked:
receivers times reads. 6,000 objects made at top level, half of them handed to code from disk: 22,599 M instructions for 11,154 M. Now one
question for all of them first: does any accessor of the program lie on or above any of them under the key.

* AOT: asking an error of a class of one's own for its own names runs Error.prepareStackTrace

Where the engine is asked for an own name of an error, or for all of them, it makes the error's stack, and the program's
Error.prepareStackTrace runs in the middle of the call. For an instance typed `Error` the compiler knew; for one typed by the layout of its
own class (`class Failure extends Error`) the step was proven free of code, so a read of what the hook writes was merged over the call:
`const before = calls; Object.freeze(failure); before + " " + calls` printed "0 0" for "0 1", without an error. Eleven operations.

* AOT: an import() of a CommonJS file that is still running takes its names when it has ended

b.cjs: `exports.early = 1; const a = require("./a.mjs"); exports.late = ..`. a.mjs: `import("./b.cjs")`. `const b = await import("./b.cjs")`:
in node and in `bun build --compile` the keys are `default,early,late`; compiled ahead of time `default,early`, and b.late undefined. Where
b.cjs throws behind the require(): in node the require() throws and the import() is rejected; compiled, the error was lost.

* AOT: four more rankings go by a key that is cut short of its last digits

Behind "two layouts that are made equally often are ranked alike": the order of the arms of a planned slot, which optional fields of a
layout lie in line, which conditions are kept past the limit on tested types, and the percentiles of density all ranked sums of products
over the whole program, so that a rounding error could choose. Each key is cut once; ties go as before. On 15 public programs one function
changes.

* AOT: four mends in the run time's modules

- A test file with a hoisted `vi.mock("node:fs", ..)` never finished loading. It came with "`bun test --aot` as one program settles
  import() calls as the executable of the same files does".
- Over two layers a mock factory that had failed was called once too often where the mocked module was taken out of the cache. It came
  with "over layers, the mock of one test file leaked into the next".
- With the exception-scope validator on, keepFailureOfRequest() ended the run: it has a scope of its own now. It came with "behind
  vi.resetModules() a failed import fails again in the same words".
- In a test run, a load of a compiled file by a computed path out of code from a string is refused in words that are true of a test run,
  and the run's closing lists count such loads. An executable's words are as they were.

They share AOTModules.cpp. Goes with Bun's half.

* AOT: the README says that no pass merges or removes a call of a host function

Beside the advice for a pass that moves an allocation: no pass merges or removes a call of a host function or getter. The rows of the
built-ins are relied on for that and are not checked against it: what a call changes may be read through another object, or be ambient.
No code changes.

* AOT: over layers, a package under vi.mock reaches a file that an earlier test file loaded

user.js: `import { flag } from "pkg"`. a.test.js imports the user. b.test.js has `vi.mock("pkg", () => ({ flag: "mock" }))` and imports
the user by a statement. c.test.js imports the user. Plain: real, mock, real. Compiled over layers: real, real, real. With vi.mock and
vi.doMock, an ES and a CommonJS package; mock.module was right, and so was one program.

`bun test` lets go of the importers that earlier test files left when a Vitest mock meets a loaded module that it leaves alone. The
compiled counterpart was called only where a mock is laid over a module. Goes with Bun's half.

* AOT: JSON.stringify of a ring of records through lists threw a RangeError for a TypeError

`interface Ring { size: number; below: Ring[] }`, eight or more of them, each in the list of the one before and the first in the list of
the last; `try { JSON.stringify(ring) } catch (error) { error.name }` in a function that runs twice. Plain:
`TypeError: JSON.stringify cannot serialize cyclic structures.` Compiled: `RangeError: Maximum call stack size exceeded.`

* AOT: an expectation is proven only inside its operand's type

A verifying build stopped with "verification failed after SimplifyControlFlow; .. TypeOutOfDate .. (Expect)" on
`if (Array.isArray(value)) record.m = value;` in a function that only `undefined` and an arguments object reach. An expectation counts as
proven by the tests in front of it; what they leave was worked out without the operand's own type.

* AOT: the verifier asks nothing of an assumption that nobody reads

A verifying build stopped with "verification failed after SimplifyControlFlow; .. StoredTypeMismatch .. (AssumeType)" on a call through
`.apply` with a list made at the call site, resolved behind a test of the callee to a function whose parameter is proven a list of small
integers. The arm is dead, and nobody reads the assumption: no code is made for it, and none by it.

* AOT: a list whose constructor or prototype was changed through an unknown object is no plain Array

What map, filter, slice, concat, flat and splice answer on a list was proven a plain Array although the list's `constructor` (with
Symbol.species) or its prototype had been changed: `const target = foreign.none ?? own; target.constructor = { [Symbol.species]: .. }`, or
Object.setPrototypeOf, Reflect.setPrototypeOf or `__proto__ =` on such a target, where the list has escaped and the changing code is
reached late. `Array.isArray(it.map(x => x))`: plain false, compiled true. `it.slice().constructor.name`: plain Sub, compiled Array.
Without an error. Goes with Bun's half.

* AOT: four mends in the run time's mocks and modules

- Over layers: `vi.doMock(m, f1); const user = await import("./user.js"); vi.doUnmock(m)`, or a second mock; then `user.read()`. Plain
  reads f1's values for as long as the object is held. Compiled over layers it read `undefined`, the real module, or the second mock.
- A preload has `vi.mock("./dep.js", () => ({ who: "preload" }))` and `import "./helper.js"`, which imports dep.js; a test file has
  `vi.mock("./dep.js", () => ({ who: "file" }))`. Plain: the file and what it loads read `file`, and helper.js goes on reading `preload`.
  Compiled: `file` everywhere.
- The original of a built-in module under a mock. `mock.module("undici", async importOriginal => ({ ...(await importOriginal()) }))`
  behind a require("undici") failed with ENOENT in the first test file of a run; so did bun:sqlite, bun:jsc, bun:ffi, ws, node-fetch and
  three more. Under a bare vi.mock("bun:sqlite") behind an import of it, require("bun:sqlite") answered the class Database instead of the
  module's exports.
- Behind "a request to terminate a Worker waits behind an entry file that has run": by reading, twelve more checks of that kind stand
  behind the body of a CommonJS file, whose record never stands on the stack of the evaluation. A request to terminate that comes back
  while the record has been evaluated without an error of its own is now filed on the record at the one door into our evaluation.

They share AOTModules.cpp. Goes with Bun's half.

* AOT: build time: a long row of classes, each with a method

What was asked of each class by a walk to the top of its row is answered for all layouts at once, a step for each layout, at eleven sites.
3,125, 6,250, 12,500 and 25,000 classes on one thread: 8.2, 25.3, 87.6 and 324.8 G instructions before; 5.6, 14.6, 44.9 and 153.9 G now.
What is left is no walk: a type is the sorted list of its layouts, and a row of n classes has n lists of n/2. Goes with Bun's half.

* B3: an ahead-of-time build stops where fixSSA would invent a value

Where no Set reaches a read of a variable, or an edge into a live Phi, fixSSA puts a zero there, so a phase that loses a Set gave a wrong
answer without an error. Under `optimization.checksVariablesAreSet`, which only the ahead-of-time policy sets, the build now stops there
with VariableReadBeforeSet. The JIT's policy has the flag off.

Beside it: `validation.takesIdentitiesInHeadersForPhis`, off by default, brings an old fault of versionLoops back for a test; and clearer
names in B3FoldPathConstants.cpp.

* AOT: the one question for all receivers is asked of a set that the statement is woken for

It came with "build time: one question for all receivers first". Under `--aot-check=flow-fixpoint` a build stopped with
"FlowEndedTooEarly: the flow analysis was at rest, and 2 of its rules still add something when they run once more over the solved sets".
The question was asked of the receivers that have not escaped by now, which leaves no watch: when a receiver escaped later, the statement
was not woken. It is asked of all the known receivers now; who has not escaped is asked behind it, as before.

* AOT: a spy on call, apply or bind of a library function is refused aloud

`const s = spyOn(Array.from, "call"); Array.from.call(Array, [1]); s.mock.calls.length`: plain 1, compiled 0, and the test passed; with a
mockImplementation the real function answered. Compiled code takes call, apply and bind of a built-in function for what
Function.prototype holds. A function of the engine or the host refuses them as properties of its own; for a function of the library that is
written in JavaScript spyOn() never asked. It is refused now in the words of the others. In `bun test --aot` alone. Goes with Bun's half.

* AOT: one value under two local names, tested by truth, lost its null: the other order of the comparison

It completes "one value under two local names, tested by truth, lost its null", which cured `b === a` alone.
`function f(a, b = a) { if (!a) { if (a === b) seen.push(typeof (a ?? "d")); b ^= 1; } else a == b; return b?.[0]?.[0]; }` called with
-1, 1, "", "1", null: plain `string,string`, compiled `string,number`, without an error. Bun's main has it too. PlaceTypeTests laid a third
cast whose claim was taken while the proof still had the type made from the stand-in; like the other two it now claims the type of the
value that it replaces. Goes with Bun's half.

* AOT: build time: the walk for `module.exports` asks under that name alone

`import { getPlatformProxy } from "wrangler"` and one test under `bun test --aot` took 369 s to build, 305 s of it in the rules of the flow
analysis. For `require.cache[path].exports = other`, a store under a key that is no name went over every member of every built-in holder
among the receivers, only to ask whether one is the exports of a module object. It asks under the name "exports" alone now, and not at all
where the receivers may be an unknown object. 369 s become 271 s; the image's bytes are the same.

* AOT: a stop in compiled code ends the process also where SIGTRAP has a listener

With `process.on("SIGTRAP", ..)` listeners (the npm package signal-exit lays one) a stop in compiled code ran on (x64) or hung (arm64).
Under the image's assembler policy breakpoint() now emits an illegal instruction (ud2, udf), so the process dies by SIGILL with the crash
report; what fills the gaps between functions is hlt on x64. The JIT's policy and bytes are unchanged, which testmasm pins. Goes with Bun's
half.

* AOT: a count of the parameters that callers may let go of

A new statistic, ParametersLetGo, counted in ChooseCallingConventions: how many pairs of a function and a parameter the callers may let go
of. An IR test asks for it. No generated code changes.

* AOT: seven mends in the run time's mocks

- `mock.module("node:os", () => made)` or `vi.doMock("node:path", ..)` with a counting getter on the factory's object, over layers: four
  lines read "mock 2" for plain's "mock 1": one read of the getter too many, without an error. It came with "over layers, the mock of one
  test file leaked into the next".
- q.cjs has `const k = require("./k.js")` and was loaded by the earlier test file; behind `vi.doMock("./k.js")`, `require("./q.cjs").top()`
  read the real k for the mock's, without an error. It came with "four mends in the run time's modules"; three lines of that commit are
  taken back. What they had cured stands open again: `import * as early from "./early.js"` at the top of a test file, then
  `vi.doMock("./dep.js", ..)` and `await import("./late.js")`: early, which imported dep.js ahead of the mock, reads the mock's values; only
  in one realm over layers, and only where an earlier test file had loaded dep.js.
- barrel.js has `export * from "./dep.js"`; an earlier test file takes the barrel's namespace object; a later one says
  `vi.doMock("./dep.js", () => ({ flag: "one", plain: "one", added: "added" }))` and loads another user of the barrel. Plain:
  `one,added,added+flag+plain`. Compiled: `one,,flag+plain`. As one program and over layers.
- The same line over the layers that a run takes by itself, where the end of an earlier mock had the barrel linked anew too early.
- node_modules/reads, an ES module: `export const seen = async () => (await import("dep")).value();`; the test has
  `vi.mock("dep", () => ({ value: () => "mocked" }))`. Plain: `real`, because Vitest leaves packages as they are. Compiled: `mocked`.
- lib.ts has `export * as space from "./space"`; the module has run; `mock.module("./lib.ts", () => ({ space: { inner: "mock inner" } }))`.
  Plain: `space.inner` reads `mock inner`. Compiled: `real inner`, for a statement importer, a namespace object, import(), a captured value
  and a barrel.
- A module whose body threw stayed failed behind vi.resetModules(), behind vi.doUnmock() and in the next test file; plain loads it again.
  config.js: `if (!process.env.KEY) throw ..`; with the key set behind a reset: plain `k`, compiled `threw KEY is not set`.

They share AOTModules.cpp. Goes with Bun's half.

* AOT: the checks of slot types are not compiled for size

Under the checking modes alone (BUN_JSC_validateAOTRuntime, an image built with --aot-validate). Seven functions that run for every object
that is still alive lay under a pragma that compiles a file's functions for size, which takes no inlining to speak of. They are compiled
as other code is; what is printed before the process stops stays under the pragma. +384 bytes of text. Nothing changes at default flags.

* AOT: what a call returned is quoted where it is called and is no function

`expect(1)()`: plain `expect(1) is not a function. (In 'expect(1)()', 'expect(1)' is an instance of Expect)`, compiled
`Expect is not a function`. So too `make(1)()`, `o.n.k()(2, 3)`, `make(make(1))()`, `make?.(1)()`, `make(...[1])()` and `make({ a: 1 })()`.
Goes with Bun's half.

* AOT: an accessor that a copy brings to a locked built-in is warned of

`Object.defineProperties(Object.prototype, Object.getOwnPropertyDescriptors({ get extra() { return 41; } }))` and
`Object.assign(Array.prototype, { get at() { return f; } })` throw a TypeError at run time, as documented, but the build gave no TS100014.
With a data property the warning came. An accessor names its key as a property does now.

* AOT: a build can write down what the flow analysis hands on

`BUN_JSC_dumpAOTIR=FlowFacts=<path>` makes a build write what the flow analysis hands to ApplyFlowResults, a line for each fact, each thing
named by its place in the source, so that two builds can be compared. A tool for testing: nothing changes where the word is unset. Goes
with Bun's half.

* AOT: Bun read under a key that nobody knows keeps every member

`const d = ["$"].join(""); typeof Bun[d].braces`: plain and `bun build --compile` say `function`, compiled ahead of time `undefined`,
without an error. `Object.getOwnPropertyNames(Bun[d])`: 7 names for 2. The same for Bun.sql and Bun.SQL. The flow analysis let a key that
nobody knows name no member of Bun, on purpose; the read then answered a bare stand-in function, and a read off the stand-in is silent.
Goes with Bun's half.

* AOT: testaot says both types, and prints the body around a failed verification

Where a type differs from what its rule gives, the message ends ": there stands X, the rule gives Y". With TESTAOT_SHOWS_FAILING_BODIES=1
and --single-process testaot prints the function in front of the run that failed and behind it. Two hooks in the verifier, null in the
product, asked only behind a verification that has already failed.

* AOT: a child of a native test that crashed says how it was started

The launcher prints the whole command line of a child that crashed or hung. A test alone.

* AOT: an import cycle is entered where the first import() call enters it

- In executables, and in test runs as one program: `const first = import("./a.mjs"); await null; import("./b.mjs")`, a and b importing each
  other, a reading a name of b at once: compiled code threw a ReferenceError. The later call's graph was complete in fewer jobs, so the
  cycle was entered at b; node, `bun run` and `bun build --compile` enter it at a. Of 24,696 graphs on which the three agree, 2,438 were
  wrong and 252 are: all 1,067 errors and all 8 wrong values are cured, none is newly wrong; what is left are orders, wrong on Bun's main
  too.
- In a test, `await import("./main.mjs")` whose body awaits `import("./top.mjs")`, top importing m2 (which imports b.cjs, which requires
  a.cjs) and a.cjs: the executable and every reference print `b start, a`; the test run printed `a, b start`, without an error. It came with
  "`bun test --aot` as one program settles import() calls as the executable of the same files does".
- A test file with a hoisted `vi.mock("node:fs", ..)` never finished loading beside a test file that names `vi.resetModules()`. It came with
  the same commit; the first of "four mends in the run time's modules" had cured one form alone.
- main.cjs `require("./mid.mjs")`; mid.mjs `import { loaded } from "./reader.mjs"`; reader.mjs
  `import defer * as deferred from "./deferred.mjs"; export const loaded = deferred.loaded`; deferred.mjs
  `export const loaded = import("./reader.mjs").then(..)`: plain and `bun build --compile` print `loaded`; compiled ahead of time the promise
  never settled while the program's CommonJS entry was still running. Bun's main has it too.

They share AOTModules.cpp. Goes with Bun's half.
* AOT: the checks of slot types go by a plan for each layout

Under the checking modes alone. Holding every slot of every object that is still alive against its type was 20 to 23% of all user
instructions of the TypeScript-compiler benchmark under checked proofs: for each field anew, whether it is a brand or an accessor, where it
lies, its type and its range; and over half of the visits were to fields that the object doesn't hold. All of that is the same for every
object of a layout, so a plan is made at the first object of a layout. The plan says only whether a slot is outside its type; the old walk
then names it, so a report reads as before. Nothing changes at default flags.

* AOT: the file of what the flow analysis hands on says why

Behind "a build can write down what the flow analysis hands on": the line of a layout ends with one column more, why the analysis could not
rule more out. A tool for testing: nothing changes where the word is unset.

* AOT: a call of Math.random() is not removed or run twice

`setRandomSeed()` from `bun:jsc` makes the sequence of Math.random()
reproducible, so a program can count the calls. The compiler believed that
nobody could: the call was declared to write only the runtime's own state.

    function roll(use) {
      const r = Math.random();
      return use ? r : -1;
    }

Where `use` is false the call was removed, and every later number differed from
`bun run`. The same happened to a bare `Math.random();`, to an argument that the
callee does not read and to a property that nobody reads.

The call could also run twice. A typed function that fails a type test before
it has done anything visible starts again in its generic version:

    function f(holder: Holder) {
      const r = Math.random();
      const inner = holder.inner;
      return inner.x + inner.y + r;
    }

With an `inner` that is not laid out as a Point, `r` was the second number.

Math.random() now also reads and writes external state, as Date.now() does.
Two tests had the old effects written into them and are restated.

* AOT: the refusal of a load by a dynamic path names the flag too

"Cannot load '<path>': this executable can't load a module from a dynamic path. Pass the file to bun compile as another entry point" now
goes on ", or build with --aot-allow-code-from-disk", as the other refusal of a load does. Words alone. Goes with Bun's half.

* AOT: native code that runs out of stack in an executable is reported

Native code that ran out of stack in an executable built with --aot ended the process with SIGSEGV, nothing on stderr, no crash report, and
a raw terminal left raw. Bun's crash handler registers an alternate stack; the engine then installed its own actions for SIGSEGV and SIGBUS
over it without SA_ONSTACK, and only the thread that started had an alternate stack. A thread that has none gets one, and the two actions
take it. Goes with Bun's half.

* AOT: seven mends in the run time's modules and mocks

- `mock.module("./m.js", () => { calls++; imports.push(import("./m.js")); throw ..; })`, then two `import()`s of m.js one behind the other.
  Plain asks the factory each time (`failed 2`, `failed 3`); compiled as one program, the second was answered with the first's error and
  nothing was called, without a sign.
- A mock that works, laid over the one that failed, then `import()` by a name that the build can't read: plain `mock`; compiled, rejected
  with the first error.
- a.test: `mock.module("node:os", () => ({ EOL: "mock EOL" }))`, then a graph that ends in node:os and passes through barrel.mjs. b.test:
  `mock.module("./barrel.mjs", () => ({ own: "mock own" }))`, then `import { own } from "./outer.mjs"`. Plain: `mock own`. Over two layers:
  `SyntaxError: Export named 'own' not found in module outer.mjs`.
- main: `try { require("./file.cjs") } catch {}`; file.cjs:
  `import("./file.cjs").then(.., error => console.log(error.message)); throw new RangeError("thrown by the file")`. `bun run` takes the file
  out of require.cache at the throw, so the import() runs the file again and is rejected with what the second run throws. Compiled:
  rejected with the first error, one run.
- A plugin of the run answers for `virtual:aliased` in onResolve; `await import("virtual:aliased")` twice behind an import statement of the
  same name. `bun test` asks the plugin at every call; compiled, at the statement alone.
- a.test.js: `vi.doMock("./dep.cjs", () => ({ who: "one" })); const held = await import("./held.js")`; held.js:
  `import { who } from "./dep.cjs"`; b.test.js: `import { read } from "./held.js"`. Plain and one program: `real`. Over layers: `undefined`,
  though dep.cjs's body ran.
- main.cjs: `const a = require("./a.mjs")`; a.mjs: `import("./b.cjs"); export const fromA = ..`; b.cjs: `require("./a.mjs").fromA`. node and
  `bun build --compile`: "a ends | main has a | b starts | b sees a". Compiled ahead of time, as `bun run`:
  "a ends | b starts | b sees undefined | main has a". It goes as node and `--compile` now.

They share AOTModules.cpp. Goes with Bun's half.

* AOT: testaot can ask the laws of the algebra of types of every type of a program

`RUN: laws-of-types`: 26 laws of intersectWith, castTo, unionWith, without, isSubsetOf and overlaps over every pair, and for three laws every
triple, of the JavaScript types that a program holds: a line for each shape of pair that breaks one, and a sum for each broken law. With
TESTAOT_LISTS_BROKEN_LAWS_OF_TYPES=<file> the same behind every command of every test. A tool of the tests alone; no test pins its sums yet,
because they go by the table of built-ins that the engine is built with.

* AOT: a step of the build counts who reads a field that assumes more than a type says

aot/codegen/generator/reads-that-assume.ts counts, file by file, who names the heap of a string's value and who calls the four helpers for
flat strings, and holds the counts to aot/codegen/AOTReadsThatAssume.txt: 22 places, each with the reason why it is right. A place that the
list lacks stops the build before the first file compiles. `AOT_CHECK_READS_THAT_ASSUME()` in aot/AOT.cmake runs it here; Bun's build has
its own step. No generated code changes.

* AOT: the build warns of a store under a name that native code locks on a host object

`process.versions.node = "1.2.3"` and its like throw at run time, and the build gave no warning. The table of built-ins now says which names
native code locks, and the check for writes to locked built-ins reads it. It feeds a diagnostic alone: no answer of a program and no
generated code changes. Goes with Bun's half.

* AOT: the end of a mock gives back what the mock replaced

Behind the sixth of "seven mends in the run time's mocks". a.js and b.js both have `export * as inner from "./inner"` and both are mocked;
then `vi.doUnmock("./b.js")`. Plain gives back what b's mock replaced, `mock of a`; compiled code read `real`. A mock that replaces a
namespace that is handed on now keeps what stood there, and its end gives that back. A parameter that nothing read is gone. Goes with Bun's
half.

* AOT: a link that fails behind a computed name throws at the load, in plain's words

`for (const file of ["one.js", "broken.js", "two.js"]) await import("./" + file)`; broken.js: `import { nope } from "./dep.js"`. `bun run` and
`bun build --compile`: `SyntaxError: Export named 'nope' not found in module '..dep.js'.` Compiled ahead of time:
`ResolveMessage: Cannot find module '/$bunfs/root/broken.js' imported from '/$bunfs/root/broken.js'`. Where broken.js only imports the file
with the fault, the build was refused where `--compile` builds. Goes with Bun's half.

* AOT: the statistics tell the lines of packages, of declarations and of Bun apart

Four more statistics beside SourceBytes and SourceLines, for `bun build --compile --aot`'s new closing words, "compiled 57,464 lines in
18.64 s (3,082 lines/s)". Counters alone. Goes with Bun's half.

* AOT: the detail of a stale type names an operand only where there is one

It came with "testaot says both types, and prints the body around a failed verification". Behind a TypeOutOfDate the detail read the first
operand after asking only how many there are; an optional operand that is left out (NewObject's prototype) is an empty id, and testaot died
by SIGSEGV where it should have named the stale type. The block runs only where testaot has set the printer of types: no product build
enters it.

* AOT: a store that is listed at its allocation goes by the proof of the pass

A verifying build stopped with "verification failed after SplitUnions; .. (PropSet) in b0 may throw or run code, and is gone". The removal
is right: `v24 = NewObject ..; PropSet v24, v12 key="inner"; FinishObject v24` becomes `NewObject -, v12, ..`, only where the store's plan is
a plain store to a slot of an object that the function has just made. The check asked too much. Goes with Bun's half.

* AOT: a test: a number stored into a new extension has the owner's barrier

The barrier for a new extension is decided as if a cell were stored, whatever the value's type. A build that decided by the value's type
would have passed every other test. A pair of tests alone, as shipped and with the planted fault StoresNeedNoBarrier.

* AOT: require() asks what the imports under a type have made of a data file

`import typed from "./data.json" with { type: "json" }` and `require("./data.json")` in one program gave two objects in compiled code: a store
through one was not seen through the other, without an error. Under `bun run` require() hands out the namespace of what the import made,
whose default is that one object; `bun build --compile` has one object too. Goes with Bun's half.

* AOT: a test pins the laws of the algebra of types over the types that it names

Behind "testaot can ask the laws of the algebra of types of every type of a program": `RUN: laws-of-types` takes for its corpus the types
that the test names, so its sums no longer go by the table of built-ins that the engine is built with. tests/types/laws.ir: 21 types, 20 of
26 laws hold; the sums of the other six may only shrink. Tests alone.

* AOT: a delete by key looks at the key, and an assignment asks for the target's prototype

Two wrong answers of executables at default flags, without an error; Bun's main has both.

- `Reflect.deleteProperty(Object.freeze({ m: y }), "m")` answered true for false. Nobody read the field, so it was removed, and the delete
  found nothing to refuse. A delete by key now looks under its key, as a test does.
- `Object.assign({ __proto__: { set a(v) { o.b = "S"; } } }, o).b` gave "x" for "S". The expansion reads every field of the source first,
  and the setter that the target inherits ran too late. Such a call stays a call.

Goes with Bun's half.

* AOT: the file of what the flow analysis hands on has no blind spot

Behind "a build can write down what the flow analysis hands on": a check that simply stays, and a call whose callees nobody knows, had no
line, so two builds that differ in hundreds of them read alike. Every check and every call of a value in a function that is entered has a
line now. A tool for testing: nothing changes where the word is unset. Goes with Bun's half.

* AOT: Bun read under a key that nobody knows keeps what code of the library makes, not every member

It narrows "Bun read under a key that nobody knows keeps every member". Where that rule fired, all 115 members of Bun counted as used,
Bun.FFI and Bun.Transpiler among them, and `--trim` kept the run time whole: one large application grew from 428.9 to 475.8 MB. Only the 16
members that code of the library makes ever got the bare stand-in whose members read `undefined`; they alone are kept now. What native code
makes is there whoever reads it. `typeof Bun[d].braces` stays `function`. Goes with Bun's half.

* AOT: testaot asks for its process id the portable way

It came with "testaot can ask the laws of the algebra of types of every type of a program": `<unistd.h>` and getpid(), for the name of the
file that TESTAOT_LISTS_BROKEN_LAWS_OF_TYPES asks for. The Windows lanes have no such header: "fatal error: 'unistd.h' file not found".
getCurrentProcessID() of <wtf/ProcessID.h> instead. A test tool alone.

* AOT: a long text with accents is encoded by the library

`new TextEncoder().encode(text)` and `.encodeInto()` of a Latin-1 text with accents took 10 to 14 times as long in an executable as under
`bun run`: one scalar loop counted the text and a second wrote it a byte at a time. Over 16 characters simdutf does both now, as plain Bun's
encoder does; up to 16 characters the old loops stay. Goes with Bun's half.

* AOT: a call for a module of a graph under way settles behind the call for the graph

main: `import("./a.mjs").then(x); import("./b.mjs").then(y)`; a.mjs: `import "./c.mjs"`; b.mjs: `await import("./c.mjs")`. node, `bun run`
and `bun build --compile`: b begins, c runs, a runs, x, b ends, y. Compiled ahead of time: b begins, c, a, b ends, x, y, without an error.
The modules ran the same; the order in which the calls settle didn't. Goes with Bun's half.

* AOT: a refusal that the run time cannot decide decides no exact test

At the IR alone: no JavaScript was found that shows it. `v1 = TypeTest v0 testedType=builtin(ImportMeta)`; on its refusal
`v2 = AssumeType v0 provenType=number|builtin(ImportMeta); v3 = TypeTest v2 testedType=builtin(ImportMeta)`: the verifier admits it, and
SimplifyControlFlow decided v3 false and assumed a number. With an IR test.

* AOT: what only an image of the library alone reached is deleted

The engine's half of the build option `--compiledLibrary`, which Bun no longer has: two options of the compile call, the flag of an image
(its bit stays free; no other flag's bit moves), and what only they reached. It needs a Bun without the option.

* AOT: a planted fault that drops the card of a variable

A word for the tests, and an IR test that is red with the word and green as shipped. No product code. Goes with Bun's half: each is red
without the other.

* AOT: a test run lists the compiled files that ran from source, and why

In `bun test --aot` a file that the image holds ran from its text in the interpreter, without a word, behind `import("./a.js?" + n)`,
`vi.resetModules()`, `delete require.cache[..]`, and where a `Bun.ModuleGraph` imported it: such tests don't test the code that an
executable runs. The run time notes each such file with its reason, for one list. No answer of a program changes. Goes with Bun's half.

* AOT: the stubs align with the same padding as the rest of the code

On arm64 the padding that aligns the stubs was still a breakpoint (the assembler's align() emits brk), so with `process.on("SIGTRAP")`
listeners a wild jump into it hung. The stubs align with udf now, as the rest of the code does. x64's bytes are unchanged. Goes with Bun's
half, whose arm64 case is red without this.

* AOT: an image that has noted no load has no moments

By reading: no program was found that fails. Two functions of the run time's modules read the list of the moments of loads without asking
whether the image has noted a load, and three callers came without the guard that the others have. Both ask it themselves now: an image
without moments answers with the module's own place, and "not loaded in this test file".

* AOT: the recheck of guards reads only what its functions reach

Build time under the program verifier alone: no byte of any output depends on it. Where the first verification reports a guard that isn't
available, the summaries of effects were computed over the whole program from nothing, twice, to verify a few functions again. Now they are
computed over what the bodies of those functions name; every other function counts as unknown code.

* AOT: the iterator of a map is told by its cell

The table of built-ins gives %MapIterator% its cell type, so the algebra of types tells it from Map and Array (the meet is never, both
ways). Two tests, red without it: seven iterators pass, made by the shell, by compiled code, of a class below Map, with the prototype taken
away; fourteen others, the prototype object and an heir of it among them, don't. Goes with Bun's half.

* AOT: a guard that is not available names what may have ended it

Behind GuardNotAvailable the verifier's detail says which guard it is and, of the operations in front of the use that may end what it
proves, the nearest six. It needs no printer of types, so a build under `--aot-check=verify-each-pass` says it too. A diagnostic alone.

* AOT: a cast may stand between the header's parameter and the step of a for-in

`bun build --compile --aot main.js` ended with exit 134, 'panic: abort() called', 'Stopped while compiling a function (main.js:4) in
ExpandOwnKeys'. Bun's main has it.

`function f1(L) { for (const q in L) { if (L[+q] === 2) return 1; } return 0; }`, declared in a callback that is kept and called later, and
called in a try in a loop over `const L = [2]`. A test's body is such a callback. The pass took the position that the step takes for a
parameter of the loop's header, which no rule of the IR says: a cast may stand between them.

* AOT: the iterator of a set is told by its cell

As "the iterator of a map is told by its cell", for %SetIterator%. Its lines in the same two tests: seven iterators of sets pass, whoever
made them; the iterators of maps and sixteen others don't. Goes with Bun's half.

* AOT: an object held from ahead of the mock never reads the mock

`import * as early from "./early.js"` at the head of a test file, then `vi.doMock("./dep.js", ..)`: early.js read the mock's values of dep.js
where `bun test` reads the file's, without an error: in one realm, in a run that is built in layers, with dep.js loaded by an earlier test
file. Of the two places where a mock can answer a read from outside, only the first respected that the module is read past its mock. Goes
with Bun's half.

* AOT: one forward walk builds a body anew in place of the compaction's five helpers

aot/ir/AOTForwardWalk.{h,cpp}: a walk that reads a body once, in an order in which a block stands behind the blocks that dominate it, and
builds the body anew while it reads. compactFunction() calls it, and the five static helpers that it replaces go. The order of the blocks is
today's. No output changes.

* AOT: an import of a module that compiled code began settles when it has run

main.mjs: `require("./mid.mjs")`; mid.mjs: `import "./a.mjs"; require("./b.mjs")`; b.mjs: `import("./mid.mjs").then(settled, settled)`.
`bun run` and `bun build --compile`: settled. Compiled ahead of time the promise never settled: exit 0, and nothing said. The same with
`await import("./mid.mjs")` in the entry, with `await` in an async function of b, and with two calls. Goes with Bun's half.

* AOT: the jobs behind a delivered text run ahead of the next file's body

Under `bun test --aot`, `import("./a.js").then(() => setTimeout(() => { import("./b.js"); /* thirty awaits, then a line */ }, 0))` ran b's
body ahead of the thirty jobs. `bun test` runs the jobs first, because a file's text comes in a later turn. It came with "an import cycle is
entered where the first import() call enters it"; Bun's main is wrong there too. Goes with Bun's half, which calls a new entry of the run
time.

* AOT: a call or a new in the place of what is constructed is quoted as Bun prints it

`const p = Object.create(K.prototype); new p()`. Plain: "K is not a constructor (evaluating 'new (Object.create(K.prototype))')". Compiled:
"K is not a constructor": the quote was missing, or wrong: 'new make', 'new new K', 'new q' for `new p.q()`. 71 of 158 forms differed. The
text of an error alone. Goes with Bun's half.

* AOT: a closure that a callee hands back keeps what it captured

`function lender(way, n) { let a = n * 2; const r = way(() => a++); a += 10; return r; }`, where `way` is one of fifteen functions at that
site and the one that runs is `function returnsIt(f) { return f; }`. The closure called later: plain prints `12 13`; compiled code printed a
wrong number or crashed. Goes with Bun's half.

* AOT: the recheck of guards scans for borrowed parameters only what it reads

Behind "the recheck of guards reads only what its functions reach": build time under the program verifier alone. Each of the recheck's two
readings still made the table of borrowed parameters from nothing, by a scan of every body of the program. Now the scan takes the bodies
below the functions under recheck, and the second reading takes the first one's table. `--aot-check=verify-each-pass` and a validating
build gain the second too.

* AOT: an import of a file of an image below walks its mocks once

`vi.doMock("./k.js", async () => { .. await .. }); vi.doMock("./m.js", async () => { .. }); await import("./a.js")`, where a.js imports k and
m, in a test file behind another test file whose mock's factory has run. `bun test`: k's factory begins, k's ends, m's begins, m's ends.
`bun test --aot` over two or three layers: k begins, m begins, m ends, k ends, without an error. For a file of an image below, import()
walked the mocks twice, and nobody read the second walk's answer.

* AOT: a copy of a parameter that holds -2 is not taken for 0

A wrong answer of an executable at default flags, without an error. It came with oven-sh#982; Bun's main is right.

    const T = [];
    function f(a, b) {
      let c = b;
      if (!b) {
        if (c !== b) T.push(1);
      }
      b == c;
      b?.[0];
      if (a == b) {
        b -= 1;
        c--;
        if (typeof c === "object" && c !== null && "id" in c) T.push(2);
      }
      T.push(b, c);
    }
    f(1, 0); f(-2, -2); f(1, ""); f(null, undefined);
    console.log(T.map(String).join(" "));

`bun run` prints `0 0 -3 -3   NaN NaN`; compiled code printed `0 0 -3 -1   NaN NaN`. While type tests are placed, a condition's first proof
stands for all of its proofs, and a cast took its claim from such a stand-in: the type inside `if (!b)`, `undefined|0`. A claim is taken
only from a value that stood before the run of the pass. Two IR tests, one with a planted fault. Goes with Bun's half.

* AOT: what is asked of the objects of every escaped class is asked once

Build time, quadratic in a made-up shape and next to nothing on a real program. `class A0 {} class B0 extends A0 {} globalThis["a" + 0] = B0`,
n times: every class that is out of sight has the objects of every such class among its own, and one step of the flow analysis read every
member of every layout's set: n layouts by n objects. Now a layout keeps its own objects and two bits, and what is asked of every member is
asked of each shared set once. The answers are joins, so the order can't move them. Goes with Bun's half.

* AOT: a test that runs the frames pass alone gives the verifier the tables that the pass published

The test tool's road for one pass hands the verifier no results of the flow analysis, so under `check=VerifyEachPass` it reported
CalleeRetainsFramePointer for a callee that AllocateInFrames had just proven to keep nothing. Where the verifier's inputs hold no flow they
get the pass's own table. In a build the inputs always hold it: no output changes. With an IR test.

* AOT: two system calls at the start of an executable, and only its own handler is changed

Behind "native code that runs out of stack in an executable is reported", which cost every start four `rt_sigaction` calls and one
`sigaltstack`: a compiled hello world made more system calls than a plain executable. The main thread is no longer asked whether it has an
alternate stack, because the host gave it one before the engine started; and only SIGSEGV is looked at, but on Darwin, where running into a
guard page raises SIGBUS.

`SA_SIGINFO` says nothing about whose an action is: a library that sets its own SIGSEGV handler had `SA_ONSTACK` forced on it. Now only a
handler that lies in the executable's own text is changed. Goes with Bun's half.

* AOT: the mocks of one handed-on namespace stand in a stack

It replaces the way of "the end of a mock gives back what the mock replaced". m1.js and m2.js each have `export * as ns from "./h.js"`; a test
lays mock A over m1, then mock B over m2.

- `vi.doUnmock("./m1.js")` while B stands: compiled code read `real | real`; `bun test` reads `B | B`.
- Then `vi.doUnmock("./m2.js")`: the end gave back what B had replaced, A's value, though A had ended. Every later test file of the realm
  read A, and nothing cleared it.

The mocks that replace one namespace stand in a stack that is kept with the module whose object is handed on. The latest answers; an end
takes its own entry out wherever it sits; when nothing is left the module's own object is handed on. There plain `bun test` leaves the first
mock's object in place: a difference that is meant. Goes with Bun's half.

* AOT: a declared iteration may step the iterator itself

It mends "the iterator of a map is told by its cell" and "the iterator of a set is told by its cell", under `--aot-validate` alone: no answer
was wrong at default flags. Every validating executable ended by SIGABRT at `Array.from(map.values())` and `map.values().toArray()`:
"AOT native call: .. internal state changed, the entry writes , not InternalFields". An entry that says that it iterates its operand writes
nothing by itself; the write is `next`'s, and native code steps the iterator.

* AOT: fix the macOS build

AOTForwardWalk.cpp uses entryBlock without including AOTCFG.h, which declares
it. AOTModules.cpp writes ArrayAllocationProfile inside namespace JSC::AOT,
where the name can also mean JSC::AOT::ArrayAllocationProfile, so the call to
constructArray() found no overload.

Both compiled only because of what stood earlier in their unified-source
bundles. Adding a file moved the bundles on macOS.
…and one walk (oven-sh#997)

The middle and the back end of the ahead-of-time compiler are written anew. The flow passes and the
B3 back end go; in their place stand a scan, a link, a plan, one walk over each function, a sweep and
a code generator of its own. `ir/`, `codegen/`, `stubs/`, `runtime/`, `object/`, `image/` and
`builtins/` are kept, and changed where they met the old middle.

What changes outside `aot/`, by folder, file and line, and what a program that is not compiled ahead
of time sees of it, is listed in the description of the pull request: 131 files and 539 hunks, of
which 157 are on a road that such a program takes. WebAssembly ahead of time moves from OMG to BBQ;
BBQ's code for a plain module was compared with main's over 4.3 million functions on x64 and arm64
and is the same. `Source/bmalloc` does not change.

The 53 commits of the branch, each with what it fixes and what was run for it, stay readable on the
pull request.
…runs with mocks, builds that grew (oven-sh#999)

AOT: fixes behind oven-sh#997: silent wrong answers, a crash in test runs with mocks, builds that grew

Fixes alone, on 42067fc. Outside aot/ five files change: see "Outside aot/".

Fixed:

- Old, silent, as users build: `receiver.f(swap())` called the function that the argument had just
  stored. With `class A { f(x) {..} } class B { f(x) {..} } class H {}`, `const held = new H();
  held.f = x => x + 1000;` and `function swap() { held.f = another; return 1; }`, a loop over `[a,
  b, held][turn % 3].f(swap())` called what `swap()` had just stored under `held.f`, where `bun
  <file>` calls the function that lay there before the arguments ran: 308 for 208. The read of the
  method was left to the call, behind the arguments, where every other receiver's read counted as
  constant; a field that is appended from outside the constructor counted so too. It is asked of the
  planned layout as well (aot/walk/AOTWalkUnionTableCalls.cpp: +2 -1). The call through the table
  stays where nothing stands between the read and the call. 13 stored programs in Bun's tree.

- Old, silent, as users build, the ordinary spelling among them: a later source of `Object.assign()`
  or of a spread was read as it was made, not as it is by then: `Object.assign({..}, defaults,
  this.options)` behind a getter; a source that a variable of the file, a captured variable, a field
  of a holder or a helper's parameter also holds. And `Object.assign(t, s, t)` with `t` a literal in
  sight laid the old fields over the new. A source is made again in sight only where it is a value
  of this walk that nobody else holds, and an operand behind the sources that names the target is
  the target as it is by then (aot/walk/AOTWalkCopiesOfObjects.cpp: +7). 26 stored programs in Bun's
  tree.

- Old, silent, as users build: the order of an object's keys could be wrong behind a store during
  which code of the program runs (aot/runtime/AOTPropertyCachesOperations.cpp: +10 -1). It only
  narrows what a store remembers. 4 stored programs in Bun's tree.

- Old: a test run that mocks a module and ends the mock could crash (aot/runtime/AOTModules.cpp,
  AOTModules.h, AOTModuleRecord.h, AOTTestRunFactories.cpp, runtime/AbstractModuleRecord.cpp,
  AbstractModuleRecord.h: +35 -9). Known: in such a test run a barrel of CommonJS stars with many
  importers loads slower with it: +0.7%, +7.9%, +19.6% at 200, 800, 1,600 importers, measured on the
  working tree. Not fixed here.

- Old, silent, test runs with module mocks, an everyday spelling: `vi.doMock("./mid.js", async
  original => ({ ...(await original()), extra: 1 }))` where `mid.js` holds `export * from
  "./tools.cjs"; export * from "./early.js"` and `early.js` holds `export * from "./tools.cjs"`: the
  original had no names (`both=undefined,kept=undefined` for `both=file,kept=1`);
  `vi.importActual()` alike. The record of a CommonJS file and the record of its face name one
  binding (aot/runtime/AOTModules.cpp, one function: +3 -2). 37 files of stored test runs in Bun's
  tree.

- Old, silent, test runs with module mocks: the factory of a mock that requires its own CommonJS
  file, where the build lets that file leave the program (a line of the run names its key in
  `require.cache`): `bun test` runs the file once and the mock lies over the real module; compiled,
  a TypeError (aot/runtime/AOTModuleEvaluation.cpp: +7). 15 files of stored test runs in Bun's tree.

- Old: a build could hang on a program with a very wide switch, object or module
  (aot/facts/AOTFactsRegExpTexts.cpp: +11 -2). 4 stored programs in Bun's tree.

- Old: a build could take much memory and time on a program that makes many long lists as it starts:
  the run that a build makes of the start of a program priced an operation at one, whatever it made.
  A place that is filled books its bytes in the room that stands, and sixteen places cost an
  operation; no new bound and no new number (aot/facts/AOTFactsRegExpTexts.cpp: +22). 2 IR tests, 1
  test file in Bun's tree. It does not end the kind.

- Old, loud: right typed programs were refused with TS100031: an `int32` out of `slice()`,
  `filter()` or `sort()`, and a cast that is only expected, asked where the walk no longer names
  what it casts (aot/walk/AOTWalkInt32Promises.cpp: +52 -2). 10 stored programs in Bun's tree.

- Old, loud, the engine's half: a load under a name that nobody knows threw where `bun <file>`
  answers, though the program writes a library module's name as the key of a literal, of a store, of
  a class member or as a joined key (aot/facts/AOTFactsOfProgram.cpp: +34 -1). The other half is
  Bun's.

- Slower, no answer wrong: in an executable built with `--external` or `--aot-allow-code-from-disk`,
  no module's value stayed in sight, so what one file of the library imports from another was no
  constant any more. What the internal files of the library hand out stays in sight
  (aot/facts/AOTLinkReach.cpp, AOTLink.cpp, AOTLinkFlow.h, AOTLinkTables.h,
  aot/image/AOTModuleTables.cpp, aot/runtime/AOTBuiltinModules.cpp, AOTModuleData.h,
  AOTModuleTable.cpp, AOTModuleTable.h: +93 -5). 3 new IR tests, 1 changed, 131 lines of native
  tests, 1 test file in Bun's tree. No time was measured on this tree.

Outside aot/:

- runtime/AbstractModuleRecord.cpp (+1 -1), AbstractModuleRecord.h (+3): for the crash in test runs,
  above. Both stand inside `#if ENABLE(AOT)`. The first is one more condition in a test that is
  reached for a record of compiled code alone; the second is one protected inline function. No
  member is added. A program that is not compiled runs neither.

- wasm/WasmBBQJIT64.cpp (+1 -1), toward upstream's text: the baseline JIT of WebAssembly asks for
  atomics as upstream asks (`isARM64_LSE()`) where no image is built. On Linux both questions read
  one bit; no test.

- JSTests/stress/intl-datetimeformat-language-change-mid-construction.js (+3),
  JSTests/BUN-TEST-DIFFERENCES.md (+2 -1): upstream's test on timing, which failed once on the arm64
  lto-hardened lane at 3c42aae and passed when its job was run again, is marked `serial!`.

On a build of this commit with the sources of Bun's side of these fixes, Linux x64, release, no LTO:
it compiles and links; the engine's 2,567 IR tests pass (2,562 at 42067fc); the block of
thread-local storage is 23,504 bytes, as before. Nothing else ran on it before this push: the stored
programs and test runs of these fixes run beside CI. Each fix was seen by its author to turn its own
programs on a build of the working tree; whether they turn on this text is what those runs are for.


AOT: three native tests that need Bun's table of entries wait for it

Tests alone. The last commit brought three native tests under exports-that-stay-in-compiled-code/
that name two modules of Bun's library. `testaot` as this repository builds it has the table of the
stand-in host, where their IR text does not parse, so the four test jobs with the compiler failed:
4,307 passed, 3 failed, these three. aot/tests/AOTExportsThatStayInCompiledCodeTests.cpp goes back to
42067fc's text (-131). The fix that they test stays, with its three IR tests and its test file in
Bun's tree.


AOT: mocks in test runs: one more road to a crash; a file that throws below its own factory runs again

On e8741fa. One file changes, aot/runtime/AOTModuleEvaluation.cpp (+3 -4). Nothing outside aot/.

Fixed:

- Old: a test run that mocks a module and ends the mock could crash: one more road (+1 -4).

- New with a864536, silent, test runs with module mocks. That commit let the factory of a mock
  require its own CommonJS file where the build lets that file leave the program. Where the file
  throws on its way, what its run had begun was kept, and the next `require()` of it got the exports
  as far as they were filled, with no error. With `exports.early = "half"; if (..) throw new
  Error("part fails"); exports.late = "whole";` two calls in the factory answered `threw part
  fails`, then `half undefined`, and the file ran once; `bun test` answers `threw part fails` twice
  and runs the file twice; 42067fc answers with a TypeError each time. Seen in three test runs on a
  build of a864536's text. The run that threw is forgotten here too, as on the other road that runs
  an original beside its mock (aot/runtime/AOTTestRunOriginals.cpp) (+2). Three stored test runs (9
  files) for Bun's tree, run by its own harness with the three that a864536's fix brought: 6 pass
  on the build below, 3 on a build of a864536's text, none on a build of 42067fc's.

Corrected:

- a864536's message headed the fault of that factory "Old, silent". It is a TypeError where `bun
  test` has none: loud.

- a864536's message says of the fix for a build that takes much memory and time on many long lists
  "1 test file in Bun's tree". That file is not in Bun's tree: the message of c4d68cd4 in
  oven-sh/bun says why.

On a build of a text that holds this commit's change and one other that is not in it, with Bun's
side of this branch, Linux x64, release, no LTO: it compiles and links; the engine's 2,567 IR tests
pass; the test runs above. This very tree was not built as one: its one changed file was compiled in
that build, all its other files in the build for e8741fa's text.


AOT: a field read in a loop as what the build saw stored; mocks in test runs: one more road to a crash

On a48610b. Three files, +24 -2. One of them lies outside aot/: see "Outside aot/".

Fixed:

- Old, silent, as users build. A field into which the program is only seen to store objects that it
  fills under computed keys: `class Shelf { constructor(names) { const bins = {}; for (let i = 0; i
  < names.length; i++) bins[names[i]] = i; this.bins = bins; } }`. Code made from a text stores a
  list there, `(0, eval)("(holder, value) => { holder.bins = value; }")(shelf, [1, 2, 3])`, and a
  loop of nine turns asks `Array.isArray(shelf.bins)`: false in every turn, where `bun <file>` says
  true. So too with `new Function`, with `Reflect.set` out of a text, and with a function stored and
  `typeof` asked (aot/plan/AOTSlotPlan.cpp: +5). 5 stored programs for Bun's tree. Each built alone:
  all five print what `bun <file>` prints on the build below; none does on a build without these
  five lines, nor on a build of 42067fc's text.

- Old: a test run that mocks a module and ends the mock could crash: one more road.

- No behavior: the three lines of a48610b that forget a run that threw are spelled with a `return`
  of their own (aot/runtime/AOTModuleEvaluation.cpp: +3 -2).

Corrected:

- a864536's message says that an `int32` out of `slice()`, `filter()` or `sort()` was refused with
  TS100031. Of `sort()` that is not so: the stored program for it builds at 42067fc.

Outside aot/:

- runtime/AbstractModuleRecord.cpp (+16), two places, both inside `#if ENABLE(AOT)`, for the crash
  in test runs, above. Each asks first whether the VM holds compiled code and then whether the
  record is one of compiled code; what follows is reached for a record that nobody compiled, in a
  run that holds compiled code. A program that is not compiled runs neither.

On a build of this commit with Bun's side of this branch, Linux x64, release, no LTO: it compiles
and links; the engine's 2,567 IR tests pass; the five programs above. Seven test runs print on it
what they print on a build of a864536's text. The five test runs of the factory that requires its
own file print what `bun test` prints.
…'s folder, mocks in test runs (oven-sh#1000)

Fixes alone, on oven-sh#999. Seven files, +97 -3, all under aot/. Nothing outside aot/.

Fixed:

- Old, an abort as users build. `t.mjs` holds `export * from "node:path"; export { sep } from
  "./lacks.cjs"`, lacks.cjs does not export `sep`, and another module imports `sep` from t.mjs: `bun
  <file>` prints "/"; the executable ended with exit 134. So too where the star leads to a CommonJS
  file: `export * from "./stars.cjs"; export { twice } from "./lacks.cjs"` with `exports.twice =
  function (x) { return x + x; }`, and `twice("a")` in the importer: `aa`; exit 134
  (aot/facts/AOTLinkAccesses.cpp: +2). 1 IR test; 53 files of stored programs in Bun's tree: eleven
  programs: all print what `bun <file>` prints on the build below, two on a build of 819116c's
  text. Not whole: kin of these programs are not fixed here.

- Old, the engine's part: `await import(flag ? "./other.sqlite" : "./data.sqlite", { with: { type:
  "sqlite" } })`, and the same under a name with a hole. An executable of `--compile` opens the
  database of the folder in which it runs; with --aot it opened the database of the folder in which
  it was built, under its whole path: silent where the sources still stand, "unable to open database
  file" where they do not. A load with attributes under a name that begins "./" or "../" first asks
  the host with the text as it is written; a load without attributes takes no new step
  (aot/runtime/AOTModules.cpp, AOTModules.h: +19 -2). The other parts and the test file are Bun's.

- Old, silent, test runs: who was linked under a mock that a second `mock.module()` patches read
  undefined behind its end, where `bun test` goes on reading what the second one gave
  (aot/runtime/AOTTestRunMockViews.cpp: +5). 16 files of stored test runs in Bun's tree.

- New with a864536, a build, seen in the IR alone: where the build lists the library modules whose
  names a program writes, a field without a key ended the build at an assertion. The environment of
  a closure has such fields (aot/facts/AOTFactsOfProgram.cpp: +1 -1). 1 IR test. No JavaScript is
  known that shows it.

Known, new with this change, not fixed here; both by run, on a build of it with 0e58059e of
oven-sh/bun:

- Silent, an odd program: one .sqlite file imported twice under a name made at run time, as `{ type:
  "text" }` and then as `{ type: "sqlite" }`: `bun <file>` and an executable of `--compile` hand out
  the first form again (`string string`; the other way round `object object`); compiled, each type
  gets a form of its own: `string object`, `object string`.

- Silent, small: a plugin that is added at run time, `build.onResolve({ filter: /\.sqlite$/ }, args
  => ..)`, is handed the working folder as `args.importer` for a database that is imported under a
  name made at run time; `bun <file>` and `--compile` hand it the file. Before this change that
  import was refused: "Cannot find module".

On a build of this commit but for two lines of comment in one IR test, with Bun's side of these
fixes, Linux x64, release, no LTO: it compiles and links; the engine's 2,569 IR tests pass (2,567 at
819116c), and with the table of the stand-in host 4,322 pass, none fails, 19 are left out, as
before. The two new IR tests fail on the test program of 819116c's text. On that build and on a
build of 819116c with dddebacb of oven-sh/bun: the 38 stored programs that come with these fixes:
38 | 6 pass; three families of stored test runs by Bun's own driver: 12 of 12 | 1 of 12; Bun's four
new test files: 4 | 1.
Merge upstream 5a61071 with full fork and upstream history. Port distinct require namespaces and loader-parent reachability to the new runtime and thin-summary owners; retain fork GC and memory accounting fixes. Pair hosted qualification with Bun 1d6aff3e without publishing or relabeling historical artifacts.
Use all four migrated IR fixtures from the exact Bun candidate and verify their bytes instead of downloading obsolete value-flow commands. Require four passing cases and explicitly run the require-namespace isolation and captured-export native regressions.
@socket-security

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants